<commit_before>#include <munin/button.hpp>
#include <munin/compass_layout.hpp>
#include <munin/filled_box.hpp>
#include <munin/grid_layout.hpp>
#include <munin/image.hpp>
#include <munin/scroll_pane.hpp>
#include <munin/text_area.hpp>
#include <munin/view.hpp>
#include <munin/window.hpp>
#include <terminalpp/canvas.hpp>
#include <terminalpp/string.hpp>
#include <terminalpp/terminal.hpp>
#include <consolepp/console.hpp>
#include <boost/asio/io_context.hpp>

using namespace terminalpp::literals;

struct window_event_dispatcher : public boost::static_visitor<>
{
    explicit window_event_dispatcher(munin::window &window)
    : window_(window)
    {
    }

    template <class Event>
    void operator()(Event const &event)
    {
        window_.event(event);
    }

    munin::window &window_;
};

void schedule_read(consolepp::console &console, terminalpp::terminal &terminal)
{
    console.async_read(
        [&](consolepp::bytes data)
        {
            terminal >> data;
            schedule_read(console, terminal);
        });
}

auto make_board()
{
    return munin::make_image({
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265A " "\\p+" "  " "\\p-" "  " "\\p+" "\\U265C "_ets },
        { "\\p+" "\\U265F " "\\p-" "\\U265F " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "\\U265F " "\\p-" "\\U265F "_ets },
        { "\\p-" "  " "\\p+" "\\U265B " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "  " "\\p-" "  " "\\p+" "  "_ets },
        { "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "\\U2659 " "\\p-" "  " "\\p+" "  " "\\p-" "  "_ets },
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "\\U2655 " "\\p-" "  " "\\p+" "\\U2659 " "\\p-" "  " "\\p+" "  "_ets },
        { "\\p+" "\\U2659 " "\\p-" "\\U2659 " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  "_ets },
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U2659 " "\\p+" "\\U2659 "_ets },
        { "\\p+" "\\U2656 " "\\p-" "\\U2658 " "\\p+" "\\U265C " "\\p-" "\\U2656 " "\\p+" "  " "\\p-" "  " "\\p+" "\\U2654 " "\\p-  "_ets }
    });
}

auto make_white_text()
{
    auto text_area = munin::make_text_area();
    text_area->insert_text(
        "e4 d4 e5 Bd3 Q\\i>x\\xd3 f4 c3 Nf3 0-0 b3 c\\i>x\\xd4 Bb2 a3 "
        "N\\i>x\\xd4 Rd1 B\\i>x\\xd4 Q\\i>x\\xd4 Kf2 Q\\i>x\\xb6 Ke2 Kd2 g3 "
        "a4 b4"_ets);
    return text_area;
}

auto make_black_text()
{
    auto text_area = munin::make_text_area();
    text_area->insert_text(
        "c6 d5 Bf5 B\\i>x\\xd3 e6 c5 Nc6 Qb6 Nh6 c\\i>x\\xd4 Nf5 Rc8 "
        "Nc\\i>x\\xd4 Bc5 N\\i>x\\xd5 B\\i>x\\xd4\\[3\\i>+\\x Rc1 R\\i>x\\xd1 "
        "a\\i>x\\xb6 Rc1 Rg1 Kd7 Rc8 Rcc1"_ets
    );
    return text_area;
}

auto make_content(auto &button)
{
    return munin::view(
        munin::make_compass_layout(),
        munin::view(
            munin::make_grid_layout({2, 1}),
            munin::view(
                munin::make_compass_layout(),
                make_board(),
                munin::compass_layout::heading::centre,
                munin::make_fill("\\[6\\U2502"_ete),
                munin::compass_layout::heading::east),
            munin::view(
                munin::make_grid_layout({1, 2}),
                munin::make_scroll_pane(make_white_text()),
                munin::make_scroll_pane(make_black_text()))),
        munin::compass_layout::heading::centre,
        munin::view(
            munin::make_compass_layout(),
            munin::make_fill("\\[6\\U2500"_ete),
            munin::compass_layout::heading::north,
            munin::make_fill(' '),
            munin::compass_layout::heading::centre,
            button,
            munin::compass_layout::heading::east),
        munin::compass_layout::heading::south);
}

auto make_behaviour()
{
    terminalpp::behaviour behaviour;
    behaviour.supports_basic_mouse_tracking = true;
    behaviour.supports_window_title_bel = true;
    return behaviour;
}

int main()
{
    auto button = munin::make_button(" OK ");
    munin::window window{make_content(button)};

    boost::asio::io_context io_context;
    consolepp::console console{io_context};
    terminalpp::canvas canvas{{console.size().width, console.size().height}};
    window_event_dispatcher event_dispatcher{window};

    terminalpp::terminal terminal{
        [&](terminalpp::tokens tokens) {
            for (const auto& token : tokens)
            {
                boost::apply_visitor(event_dispatcher, token);
            }
        },
        [&](terminalpp::bytes data) {
            console.write(data);
        },
        make_behaviour()
    };

    auto const &repaint_window = [&]() { window.repaint(canvas, terminal); };

    window.on_repaint_request.connect(repaint_window);
    console.on_size_changed.connect(
        [&]
        {
            auto const new_size = console.size();
            canvas.resize({new_size.width, new_size.height});
            repaint_window();
        });

    terminal
        << terminalpp::enable_mouse()
        << terminalpp::hide_cursor()
        << terminalpp::use_alternate_screen_buffer()
        << terminalpp::set_window_title("Chess++");

    auto work_guard = boost::asio::make_work_guard(io_context);
    button->on_click.connect([&]{
        io_context.stop();
        work_guard.reset();
    });
    button->set_focus();

    schedule_read(console, terminal);

    io_context.run();
    terminal
        << terminalpp::use_normal_screen_buffer()
        << terminalpp::show_cursor()
        << terminalpp::disable_mouse();
}
<commit_msg>Updated examples.<commit_after>#include <munin/button.hpp>
#include <munin/compass_layout.hpp>
#include <munin/filled_box.hpp>
#include <munin/grid_layout.hpp>
#include <munin/image.hpp>
#include <munin/scroll_pane.hpp>
#include <munin/text_area.hpp>
#include <munin/view.hpp>
#include <munin/window.hpp>
#include <terminalpp/canvas.hpp>
#include <terminalpp/string.hpp>
#include <terminalpp/terminal.hpp>
#include <consolepp/console.hpp>
#include <boost/asio/io_context.hpp>

using namespace terminalpp::literals;

struct window_event_dispatcher : public boost::static_visitor<>
{
    template <class Event>
    void operator()(Event const &event)
    {
        window_->event(event);
    }

    munin::window *window_{nullptr};
};

void schedule_read(consolepp::console &console, terminalpp::terminal &terminal)
{
    console.async_read(
        [&](consolepp::bytes data)
        {
            terminal >> data;
            schedule_read(console, terminal);
        });
}

auto make_board()
{
    return munin::make_image({
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265A " "\\p+" "  " "\\p-" "  " "\\p+" "\\U265C "_ets },
        { "\\p+" "\\U265F " "\\p-" "\\U265F " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "\\U265F " "\\p-" "\\U265F "_ets },
        { "\\p-" "  " "\\p+" "\\U265B " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "  " "\\p-" "  " "\\p+" "  "_ets },
        { "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U265F " "\\p+" "\\U2659 " "\\p-" "  " "\\p+" "  " "\\p-" "  "_ets },
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "\\U2655 " "\\p-" "  " "\\p+" "\\U2659 " "\\p-" "  " "\\p+" "  "_ets },
        { "\\p+" "\\U2659 " "\\p-" "\\U2659 " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  "_ets },
        { "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "  " "\\p+" "  " "\\p-" "\\U2659 " "\\p+" "\\U2659 "_ets },
        { "\\p+" "\\U2656 " "\\p-" "\\U2658 " "\\p+" "\\U265C " "\\p-" "\\U2656 " "\\p+" "  " "\\p-" "  " "\\p+" "\\U2654 " "\\p-  "_ets }
    });
}

auto make_white_text()
{
    auto text_area = munin::make_text_area();
    text_area->insert_text(
        "e4 d4 e5 Bd3 Q\\i>x\\xd3 f4 c3 Nf3 0-0 b3 c\\i>x\\xd4 Bb2 a3 "
        "N\\i>x\\xd4 Rd1 B\\i>x\\xd4 Q\\i>x\\xd4 Kf2 Q\\i>x\\xb6 Ke2 Kd2 g3 "
        "a4 b4"_ets);
    return text_area;
}

auto make_black_text()
{
    auto text_area = munin::make_text_area();
    text_area->insert_text(
        "c6 d5 Bf5 B\\i>x\\xd3 e6 c5 Nc6 Qb6 Nh6 c\\i>x\\xd4 Nf5 Rc8 "
        "Nc\\i>x\\xd4 Bc5 N\\i>x\\xd5 B\\i>x\\xd4\\[3\\i>+\\x Rc1 R\\i>x\\xd1 "
        "a\\i>x\\xb6 Rc1 Rg1 Kd7 Rc8 Rcc1"_ets
    );
    return text_area;
}

auto make_content(auto &button)
{
    return munin::view(
        munin::make_compass_layout(),
        munin::view(
            munin::make_grid_layout({2, 1}),
            munin::view(
                munin::make_compass_layout(),
                make_board(),
                munin::compass_layout::heading::centre,
                munin::make_fill("\\[6\\U2502"_ete),
                munin::compass_layout::heading::east),
            munin::view(
                munin::make_grid_layout({1, 2}),
                munin::make_scroll_pane(make_white_text()),
                munin::make_scroll_pane(make_black_text()))),
        munin::compass_layout::heading::centre,
        munin::view(
            munin::make_compass_layout(),
            munin::make_fill("\\[6\\U2500"_ete),
            munin::compass_layout::heading::north,
            munin::make_fill(' '),
            munin::compass_layout::heading::centre,
            button,
            munin::compass_layout::heading::east),
        munin::compass_layout::heading::south);
}

auto make_behaviour()
{
    terminalpp::behaviour behaviour;
    behaviour.supports_basic_mouse_tracking = true;
    behaviour.supports_window_title_bel = true;
    return behaviour;
}

int main()
{
    boost::asio::io_context io_context;
    consolepp::console console{io_context};

    window_event_dispatcher event_dispatcher;
    terminalpp::terminal terminal{
        [&](terminalpp::tokens tokens) {
            for (const auto& token : tokens)
            {
                boost::apply_visitor(event_dispatcher, token);
            }
        },
        [&](terminalpp::bytes data) {
            console.write(data);
        },
        make_behaviour()
    };

    auto button = munin::make_button(" OK ");
    munin::window window{terminal, make_content(button)};
    event_dispatcher.window_ = &window;

    terminalpp::canvas canvas{{console.size().width, console.size().height}};

    auto const &repaint_window = [&]() { window.repaint(canvas); };

    window.on_repaint_request.connect(repaint_window);
    console.on_size_changed.connect(
        [&]
        {
            auto const new_size = console.size();
            canvas.resize({new_size.width, new_size.height});
            repaint_window();
        });

    terminal
        << terminalpp::enable_mouse()
        << terminalpp::hide_cursor()
        << terminalpp::use_alternate_screen_buffer()
        << terminalpp::set_window_title("Chess++");

    auto work_guard = boost::asio::make_work_guard(io_context);
    button->on_click.connect([&]{
        io_context.stop();
        work_guard.reset();
    });
    button->set_focus();

    schedule_read(console, terminal);

    io_context.run();
    terminal
        << terminalpp::use_normal_screen_buffer()
        << terminalpp::show_cursor()
        << terminalpp::disable_mouse();
}
<|endoftext|>


<commit_before>/* Copyright (C) 2005 The glibmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

class ChildWatch : public sigc::trackable
{
public:
  ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}

  void on_child_exited(GPid pid, int status);
  void run(); // fork a child and call signal_child_watch

private:
  Glib::RefPtr<Glib::MainLoop> m_mainLoop;
};

void
ChildWatch::run()
{
  GPid pid = fork();

  if (!pid)
  {
    sleep(5);
    exit(0);
  }

  std::cout << "Child " << pid << " created" << std::endl;

  Glib::signal_child_watch().connect(sigc::mem_fun(*this, &ChildWatch::on_child_exited), pid);
}

void
ChildWatch::on_child_exited(GPid pid, int status)
{
  std::cout << "Child " << pid << " exited with status " << status << std::endl;
  m_mainLoop->quit();
}

int
main()
{
  auto mainLoop = Glib::MainLoop::create();

  ChildWatch cwatch(mainLoop);
  cwatch.run();
  mainLoop->run();

  return 0;
}
<commit_msg>Examples: Make a single-parameter constructor explicit.<commit_after>/* Copyright (C) 2005 The glibmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

class ChildWatch : public sigc::trackable
{
public:
  explicit ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}

  void on_child_exited(GPid pid, int status);
  void run(); // fork a child and call signal_child_watch

private:
  Glib::RefPtr<Glib::MainLoop> m_mainLoop;
};

void
ChildWatch::run()
{
  GPid pid = fork();

  if (!pid)
  {
    sleep(5);
    exit(0);
  }

  std::cout << "Child " << pid << " created" << std::endl;

  Glib::signal_child_watch().connect(sigc::mem_fun(*this, &ChildWatch::on_child_exited), pid);
}

void
ChildWatch::on_child_exited(GPid pid, int status)
{
  std::cout << "Child " << pid << " exited with status " << status << std::endl;
  m_mainLoop->quit();
}

int
main()
{
  auto mainLoop = Glib::MainLoop::create();

  ChildWatch cwatch(mainLoop);
  cwatch.run();
  mainLoop->run();

  return 0;
}
<|endoftext|>


<commit_before>/**
 * Problem 68 「Magic 5-gon ring」
 * 下に示す図のようなものを"magic" 3-gon ringという. これは1～6の数字を当てはめて, 各列の数字の和が9となっている. これを例として説明する.
 *
 * 外側のノードのうち一番小さいものの付いた列(例では4,3,2)から時計回りに回ってそれぞれ列の数字を3つ連ねて説明する. 例えば例のものは4,3,2; 6,2,1; 5,1,3という組で説明することができる.
 *
 * 1～6の数字を当てはめて, 各列の数字の和が等しくなるものは次の8通りある.
 *
 * 合計  組
 * 9 4,2,3; 5,3,1; 6,1,2
 * 9 4,3,2; 6,2,1; 5,1,3
 * 10  2,3,5; 4,5,1; 6,1,3
 * 10  2,5,3; 6,3,1; 4,1,5
 * 11  1,4,6; 3,6,2; 5,2,4
 * 11  1,6,4; 5,4,2; 3,2,6
 * 12  1,5,6; 2,6,4; 3,4,5
 * 12  1,6,5; 3,5,4; 2,4,6
 * この組の各数字を連結して, 9桁の数字で表すことができる. 例えば, 上の図のものは4,3,2; 6,2,1; 5,1,3であるので432621513である.
 *
 * さて, 下の図に1～10の数字を当てはめ, 各列の数字の和が等しくなる"magic" 5-gon ringを作って, それを表す16桁または17桁の数字のうち, 16桁のものの最大の数字を答えよ.
 *
 * (注, 3つの場合の例を見ても分かる通り, 列の始まりの数字を比べた時一番小さい数字で始まる列から時計回りに繋げるという条件のもとで文字列を生成する必要があります. この条件下で最大となる数字を答えてください. )
 */

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>

using uInt = std::uint_fast64_t;

// 3-gon
// ade
// bef
// cfd
// ==> (数列)=adebefcfd;  a+d+e == b+e+f == c+f+d

// 5-gon
// afg
// bgh
// chi
// dij
// ejf
// ==> (数列)=afgbghchidijejf;  a+f+g == b+g+h == c+h+i == d+i+j == e+j+f

// 説明のため，リングの各ノードを以上のように名付ける
// 外側のノードをa,b,...(N個)とし，プログラム中ではベクタの先頭N個に配置する
// その内aが必ず最小値になるようにする
//
// 残りのノードは，aに繋がっているものから順番に名付ける
// ベクタ中の位置もそのアルファベット順に対応する

/**
 * 題意に沿うmagic n-gon ringの場合その各ノードを連結した数値を返す
 * @param  vec リングを生成するためのベクタ
 * @param  N   何角形か
 * @return     題意に沿うリングの場合ノードを連結した数値，そうでない場合0
 */
uInt make_gon_string_num(std::vector<uInt>& vec, const uInt N)
{
  if (vec.size() < N * 2) { return 0; }
  // 和が一致するか確認しながら数列を生成
  uInt result = 0;
  uInt sum_prev = 0;
  for (uInt i = 0; i < N; i++) {
    const uInt a = vec.at(i);
    const uInt b = vec.at(N + i);
    const uInt c = vec.at(N + ((i + 1) % N));
    const uInt sum = a + b + c;
    if (i == 0) {
      sum_prev = sum;
    }
    else if (sum_prev != sum) {
      return 0;
    }
    // 3つずつの部分数列を作って，結果を生成
    uInt x = c;
    x += std::pow(10, uInt(std::log10(x) + 1)) * b;
    x += std::pow(10, uInt(std::log10(x) + 1)) * a;
    result = result * std::pow(10, uInt(std::log10(x) + 1)) + x;
  }
  // 問題文には，（求める5-gonのとき）16桁と指定があるのでここで絞っておく
  return (N != 5 || uInt(std::log10(result) + 1) == 16) ? result : 0;
}

/**
 * 1~N*2の数字からなる数列を総当りで生成しながら題意に沿うものの中から最大値を返す
 * @param  vec       数列生成用のベクタ
 * @param  N         magic N-gon ringの角数N
 * @param  depth     現在の探索の深さ
 * @param  used_nums 数列中で既に使用している数字を表すビット列
 * @return           magic N-gon ringから生成できる数列の最大値
 */
uInt best_n_gon_ring_recursive(
  std::vector<uInt>& vec,
  const uInt N,
  const uInt depth = 0,
  const uInt used_nums = 0)
{
  const uInt DEPTH_BOUND = N * 2;
  if (depth == 0) {
    vec.clear();
    vec.resize(DEPTH_BOUND);
  }

  uInt best = 0;
  for (uInt i = 1; i <= DEPTH_BOUND; i++) {
    uInt b = (1 << i);
    if ((used_nums & b) || (depth > 0 && depth < N && vec.at(0) > i)) {
      continue;
    }
    vec.at(depth) = i;
    if (depth + 1 == DEPTH_BOUND) {
      return make_gon_string_num(vec, N);
    }
    else {
      uInt res = best_n_gon_ring_recursive(vec, N, depth + 1, (used_nums | b));
      if (res > best) {
        best = res;
      }
    }
  }
  return best;
}

int main()
{
  std::vector<uInt> vec;
  uInt best = best_n_gon_ring_recursive(vec, 5);
  std::cout << "Euler068: " << best << std::endl;
  return 0;
}
<commit_msg>[Fix] small fix e068<commit_after>/**
 * Problem 68 「Magic 5-gon ring」
 * 下に示す図のようなものを"magic" 3-gon ringという. これは1～6の数字を当てはめて, 各列の数字の和が9となっている. これを例として説明する.
 *
 * 外側のノードのうち一番小さいものの付いた列(例では4,3,2)から時計回りに回ってそれぞれ列の数字を3つ連ねて説明する. 例えば例のものは4,3,2; 6,2,1; 5,1,3という組で説明することができる.
 *
 * 1～6の数字を当てはめて, 各列の数字の和が等しくなるものは次の8通りある.
 *
 * 合計  組
 * 9 4,2,3; 5,3,1; 6,1,2
 * 9 4,3,2; 6,2,1; 5,1,3
 * 10  2,3,5; 4,5,1; 6,1,3
 * 10  2,5,3; 6,3,1; 4,1,5
 * 11  1,4,6; 3,6,2; 5,2,4
 * 11  1,6,4; 5,4,2; 3,2,6
 * 12  1,5,6; 2,6,4; 3,4,5
 * 12  1,6,5; 3,5,4; 2,4,6
 * この組の各数字を連結して, 9桁の数字で表すことができる. 例えば, 上の図のものは4,3,2; 6,2,1; 5,1,3であるので432621513である.
 *
 * さて, 下の図に1～10の数字を当てはめ, 各列の数字の和が等しくなる"magic" 5-gon ringを作って, それを表す16桁または17桁の数字のうち, 16桁のものの最大の数字を答えよ.
 *
 * (注, 3つの場合の例を見ても分かる通り, 列の始まりの数字を比べた時一番小さい数字で始まる列から時計回りに繋げるという条件のもとで文字列を生成する必要があります. この条件下で最大となる数字を答えてください. )
 */

#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>

using uInt = std::uint_fast64_t;

// 3-gon
// ade
// bef
// cfd
// ==> (数列)=adebefcfd;  a+d+e == b+e+f == c+f+d

// 5-gon
// afg
// bgh
// chi
// dij
// ejf
// ==> (数列)=afgbghchidijejf;  a+f+g == b+g+h == c+h+i == d+i+j == e+j+f

// 説明のため，リングの各ノードを以上のように名付ける
// 外側のノードをa,b,...(N個)とし，プログラム中ではベクタの先頭N個に配置する
// その内aが必ず最小値になるようにする
//
// 残りのノードは，aに繋がっているものから順番に名付ける
// ベクタ中の位置もそのアルファベット順に対応する

/**
 * 題意に沿うmagic n-gon ringの場合その各ノードを連結した数値を返す
 * @param  vec リングを生成するためのベクタ
 * @param  N   何角形か
 * @return     題意に沿うリングの場合ノードを連結した数値，そうでない場合0
 */
uInt make_gon_string_num(std::vector<uInt>& vec, const uInt N)
{
  if (vec.size() < N * 2) { return 0; }
  // 和が一致するか確認しながら数列を生成
  uInt result = 0;
  uInt sum_prev = 0;
  for (uInt i = 0; i < N; i++) {
    const uInt a = vec.at(i);
    const uInt b = vec.at(N + i);
    const uInt c = vec.at(N + ((i + 1) % N));
    const uInt sum = a + b + c;
    if (i == 0) {
      sum_prev = sum;
    }
    else if (sum_prev != sum) {
      return 0;
    }
    // 3つずつの部分数列を作って，結果を生成
    uInt x = c;
    x += std::pow(10, uInt(std::log10(x) + 1)) * b;
    x += std::pow(10, uInt(std::log10(x) + 1)) * a;
    result = result * std::pow(10, uInt(std::log10(x) + 1)) + x;
  }
  // 問題文には，（求める5-gonのとき）16桁と指定があるのでここで絞っておく
  return (N != 5 || uInt(std::log10(result) + 1) == 16) ? result : 0;
}

/**
 * 1~N*2の数字からなる数列を総当りで生成しながら題意に沿うものの中から最大値を返す
 * @param  vec       数列生成用のベクタ
 * @param  N         magic N-gon ringの角数N
 * @param  depth     現在の探索の深さ
 * @param  used_nums 数列中で既に使用している数字を表すビット列
 * @return           magic N-gon ringから生成できる数列の最大値
 */
uInt best_n_gon_ring_recursive(
  std::vector<uInt>& vec,
  const uInt N,
  const uInt depth = 0,
  const uInt used_nums = 0)
{
  const uInt DEPTH_BOUND = N * 2;
  if (depth == 0) {
    vec.clear();
    vec.resize(DEPTH_BOUND);
  }

  uInt best = 0;
  for (uInt i = 1; i <= DEPTH_BOUND; i++) {
    uInt b = (1 << i);
    if ((used_nums & b) || (depth > 0 && depth < N && vec.at(0) > i)) {
      continue;
    }
    vec.at(depth) = i;
    if (depth + 1 == DEPTH_BOUND) {
      return make_gon_string_num(vec, N);
    }
    else {
      uInt res = best_n_gon_ring_recursive(vec, N, depth + 1, (used_nums | b));
      if (res > best) {
        best = res;
      }
    }
  }
  return best;
}

int main()
{
  std::vector<uInt> vec;
  uInt best = best_n_gon_ring_recursive(vec, 5);
  std::cout << "Euler068: " << best << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "spreadsheetdelegate.h"
#include <QtGui>

SpreadSheetDelegate::SpreadSheetDelegate(QObject *parent)
        : QItemDelegate(parent) {}

QWidget *SpreadSheetDelegate::createEditor(QWidget *parent,
                                          const QStyleOptionViewItem &,
                                          const QModelIndex &index) const
{
    if (index.column() == 1) {
        QDateTimeEdit *editor = new QDateTimeEdit(parent);
        editor->setDisplayFormat("dd/M/yyy");
        editor->setCalendarPopup(true);
        return editor;
    }

    QLineEdit *editor = new QLineEdit(parent);

    // create a completer with the strings in the column as model
    QStringList allStrings;
    for (int i = 1; i<index.model()->rowCount(); i++) {
        QString strItem(index.model()->data(index.sibling(i, index.column()),
            Qt::EditRole).toString());

        if (!allStrings.contains(strItem))
            allStrings.append(strItem);
    }

    QCompleter *autoComplete = new QCompleter(allStrings);
    editor->setCompleter(autoComplete);
    connect(editor, SIGNAL(editingFinished()),
        this, SLOT(commitAndCloseEditor()));
    return editor;
}

void SpreadSheetDelegate::commitAndCloseEditor()
{
    QLineEdit *editor = qobject_cast<QLineEdit *>(sender());
    emit commitData(editor);
    emit closeEditor(editor);
}

void SpreadSheetDelegate::setEditorData(QWidget *editor,
    const QModelIndex &index) const
{
    QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
    if (edit) {
        edit->setText(index.model()->data(index, Qt::EditRole).toString());
    } else {
        QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor);
        if (dateEditor) {
            dateEditor->setDate(QDate::fromString(
            index.model()->data(index, Qt::EditRole).toString(),
            "d/M/yy"));
        }
    }
}

void SpreadSheetDelegate::setModelData(QWidget *editor,
    QAbstractItemModel *model, const QModelIndex &index) const
{
    QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
    if (edit) {
        model->setData(index, edit->text());
    } else {
        QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor);
        if (dateEditor) {
            model->setData(index, dateEditor->date().toString("dd/M/yyy"));
        }
    }
}

<commit_msg>BT: opening datetimepicker in a cell in spreadsheet demo resets the date<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "spreadsheetdelegate.h"
#include <QtGui>

SpreadSheetDelegate::SpreadSheetDelegate(QObject *parent)
        : QItemDelegate(parent) {}

QWidget *SpreadSheetDelegate::createEditor(QWidget *parent,
                                          const QStyleOptionViewItem &,
                                          const QModelIndex &index) const
{
    if (index.column() == 1) {
        QDateTimeEdit *editor = new QDateTimeEdit(parent);
        editor->setDisplayFormat("dd/M/yyyy");
        editor->setCalendarPopup(true);
        return editor;
    }

    QLineEdit *editor = new QLineEdit(parent);

    // create a completer with the strings in the column as model
    QStringList allStrings;
    for (int i = 1; i<index.model()->rowCount(); i++) {
        QString strItem(index.model()->data(index.sibling(i, index.column()),
            Qt::EditRole).toString());

        if (!allStrings.contains(strItem))
            allStrings.append(strItem);
    }

    QCompleter *autoComplete = new QCompleter(allStrings);
    editor->setCompleter(autoComplete);
    connect(editor, SIGNAL(editingFinished()),
        this, SLOT(commitAndCloseEditor()));
    return editor;
}

void SpreadSheetDelegate::commitAndCloseEditor()
{
    QLineEdit *editor = qobject_cast<QLineEdit *>(sender());
    emit commitData(editor);
    emit closeEditor(editor);
}

void SpreadSheetDelegate::setEditorData(QWidget *editor,
    const QModelIndex &index) const
{
    QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
    if (edit) {
        edit->setText(index.model()->data(index, Qt::EditRole).toString());
    } else {
        QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor);
        if (dateEditor) {
            dateEditor->setDate(QDate::fromString(
            index.model()->data(index, Qt::EditRole).toString(),
            "d/M/yyyy"));
        }
    }
}

void SpreadSheetDelegate::setModelData(QWidget *editor,
    QAbstractItemModel *model, const QModelIndex &index) const
{
    QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
    if (edit) {
        model->setData(index, edit->text());
    } else {
        QDateTimeEdit *dateEditor = qobject_cast<QDateTimeEdit *>(editor);
        if (dateEditor) {
            model->setData(index, dateEditor->date().toString("dd/M/yyyy"));
        }
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/labs.h"

#include <algorithm>
#include <iterator>
#include <map>
#include <set>

#include "app/l10n_util.h"
#include "base/command_line.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"

namespace about_labs {

enum { kOsMac = 1 << 0, kOsWin = 1 << 1, kOsLinux = 1 << 2 };

unsigned kOsAll = kOsMac | kOsWin | kOsLinux;

struct Experiment {
  // The internal name of the experiment. This is never shown to the user.
  // It _is_ however stored in the prefs file, so you shouldn't change the
  // name of existing labs.
  const char* internal_name;

  // String id of the message containing the experiment's name.
  int visible_name_id;

  // String id of the message containing the experiment's description.
  int visible_description_id;

  // The platforms the experiment is available on
  // Needs to be more than a compile-time #ifdef because of profile sync.
  unsigned supported_platforms;  // bitmask

  // The commandline parameter that's added when this lab is active. This is
  // different from |internal_name| so that the commandline flag can be
  // renamed without breaking the prefs file.
  const char* command_line;
};

const Experiment kExperiments[] = {
  {
    "expose-for-tabs",  // Do not change; see above.
    IDS_LABS_TABPOSE_NAME,
    IDS_LABS_TABPOSE_DESCRIPTION,
    kOsMac,
#if defined(OS_MACOSX)
    // The switch exists only on OS X.
    switches::kEnableExposeForTabs
#else
    ""
#endif
  },
  {
    "vertical-tabs",  // Do not change; see above.
    IDS_LABS_SIDE_TABS_NAME,
    IDS_LABS_SIDE_TABS_DESCRIPTION,
    kOsWin,
    switches::kEnableVerticalTabs
  },
  {
    "tabbed-options",  // Do not change; see above.
    IDS_LABS_TABBED_OPTIONS_NAME,
    IDS_LABS_TABBED_OPTIONS_DESCRIPTION,
    kOsAll,
    switches::kEnableTabbedOptions
  },
  {
    "remoting",  // Do not change; see above.
    IDS_LABS_REMOTING_NAME,
#if defined(OS_WIN)
    // Windows only supports host functionality at the moment.
    IDS_LABS_REMOTING_HOST_DESCRIPTION,
#elif defined(OS_LINUX)
    // Linux only supports client functionality at the moment.
    IDS_LABS_REMOTING_CLIENT_DESCRIPTION,
#else
    // On other platforms, this lab isn't available at all.
    0,
#endif
    kOsWin | kOsLinux,
    switches::kEnableRemoting
  },
  {
    "disable-outdated-plugins",  // Do not change; see above.
    IDS_LABS_DISABLE_OUTDATED_PLUGINS_NAME,
    IDS_LABS_DISABLE_OUTDATED_PLUGINS_DESCRIPTION,
    kOsAll,
    switches::kDisableOutdatedPlugins
  },
  {
    "xss-auditor",  // Do not change; see above.
    IDS_LABS_XSS_AUDITOR_NAME,
    IDS_LABS_XSS_AUDITOR_DESCRIPTION,
    kOsAll,
    switches::kEnableXSSAuditor
  },
  {
    "background-webapps", // Do not change; see above
    IDS_LABS_BACKGROUND_WEBAPPS_NAME,
    IDS_LABS_BACKGROUND_WEBAPPS_DESCRIPTION,
    kOsAll,
    switches::kEnableBackgroundMode
  },
  {
    "cloud-print-proxy", // Do not change; see above.
    IDS_LABS_CLOUD_PRINT_PROXY_NAME,
    IDS_LABS_CLOUD_PRINT_PROXY_DESCRIPTION,
#if defined(GOOGLE_CHROME_BUILD)
    // For a Chrome build, we know we have a PDF plug-in, and so we'll
    // enable by platform as we get things working.
    0,
#else
    // Otherwise, where we know it could be working if a viable PDF
    // plug-in could be supplied, we'll keep the lab enabled.
    kOsWin,
#endif
    switches::kEnableCloudPrintProxy
  },
  // FIXME(scheib): Add Labs entry for accelerated Compositing,
  // or pull it and the strings in generated_resources.grd by Dec 2010
  //{
  //  "gpu-compositing", // Do not change; see above
  //  IDS_LABS_ACCELERATED_COMPOSITING_NAME,
  //  IDS_LABS_ACCELERATED_COMPOSITING_DESCRIPTION,
  //  kOsAll,
  //  switches::kDisableAcceleratedCompositing
  //},
  {
    "gpu-canvas-2d", // Do not change; see above
    IDS_LABS_ACCELERATED_CANVAS_2D_NAME,
    IDS_LABS_ACCELERATED_CANVAS_2D_DESCRIPTION,
    kOsWin | kOsLinux,
    switches::kEnableAccelerated2dCanvas
  }
  // FIXME(scheib): Add Labs entry for WebGL,
  // or pull it and the strings in generated_resources.grd by Dec 2010
  //{
  //  "webgl", // Do not change; see above
  //  IDS_LABS_WEBGL_NAME,
  //  IDS_LABS_WEBGL_DESCRIPTION,
  //  kOsAll,
  //  switches::kDisableExperimentalWebGL
  //}
};

// Extracts the list of enabled lab experiments from preferences and stores them
// in a set.
void GetEnabledLabs(const PrefService* prefs, std::set<std::string>* result) {
  const ListValue* enabled_experiments = prefs->GetList(
      prefs::kEnabledLabsExperiments);
  if (!enabled_experiments)
    return;

  for (ListValue::const_iterator it = enabled_experiments->begin();
       it != enabled_experiments->end();
       ++it) {
    std::string experiment_name;
    if (!(*it)->GetAsString(&experiment_name)) {
      LOG(WARNING) << "Invalid entry in " << prefs::kEnabledLabsExperiments;
      continue;
    }
    result->insert(experiment_name);
  }
}

// Takes a set of enabled lab experiments
void SetEnabledLabs(
    PrefService* prefs, const std::set<std::string>& enabled_experiments) {
  ListValue* experiments_list = prefs->GetMutableList(
      prefs::kEnabledLabsExperiments);
  if (!experiments_list)
    return;

  experiments_list->Clear();
  for (std::set<std::string>::const_iterator it = enabled_experiments.begin();
       it != enabled_experiments.end();
       ++it) {
    experiments_list->Append(new StringValue(*it));
  }
}

// Removes all experiments from prefs::kEnabledLabsExperiments that are
// unknown, to prevent this list to become very long as experiments are added
// and removed.
void SanitizeList(PrefService* prefs) {
  std::set<std::string> known_experiments;
  for (size_t i = 0; i < arraysize(kExperiments); ++i)
    known_experiments.insert(kExperiments[i].internal_name);

  std::set<std::string> enabled_experiments;
  GetEnabledLabs(prefs, &enabled_experiments);

  std::set<std::string> new_enabled_experiments;
  std::set_intersection(
      known_experiments.begin(), known_experiments.end(),
      enabled_experiments.begin(), enabled_experiments.end(),
      std::inserter(new_enabled_experiments, new_enabled_experiments.begin()));

  SetEnabledLabs(prefs, new_enabled_experiments);
}

void GetSanitizedEnabledLabs(
    PrefService* prefs, std::set<std::string>* result) {
  SanitizeList(prefs);
  GetEnabledLabs(prefs, result);
}

int GetCurrentPlatform() {
#if defined(OS_MACOSX)
  return kOsMac;
#elif defined(OS_WIN)
  return kOsWin;
#elif defined(OS_LINUX)
  return kOsLinux;
#else
#error Unknown platform
#endif
}

bool IsEnabled() {
#if defined(OS_CHROMEOS)
  // ChromeOS uses a different mechanism for about:labs; integrated with their
  // dom ui options.
  // TODO(thakis): Port about:labs to chromeos -- http://crbug.com/57634
  return false;
#else
  return true;
#endif
}

void ConvertLabsToSwitches(PrefService* prefs, CommandLine* command_line) {
  if (!IsEnabled())
    return;

  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  std::map<std::string, const Experiment*> experiments;
  for (size_t i = 0; i < arraysize(kExperiments); ++i)
    experiments[kExperiments[i].internal_name] = &kExperiments[i];

  for (std::set<std::string>::iterator it = enabled_experiments.begin();
       it != enabled_experiments.end();
       ++it) {
    const std::string& experiment_name = *it;
    std::map<std::string, const Experiment*>::iterator experiment =
        experiments.find(experiment_name);
    DCHECK(experiment != experiments.end());
    if (experiment == experiments.end())
      continue;

    command_line->AppendSwitch(experiment->second->command_line);
  }
}

ListValue* GetLabsExperimentsData(PrefService* prefs) {
  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  int current_platform = GetCurrentPlatform();

  ListValue* experiments_data = new ListValue();
  for (size_t i = 0; i < arraysize(kExperiments); ++i) {
    const Experiment& experiment = kExperiments[i];
    if (!(experiment.supported_platforms & current_platform))
      continue;

    DictionaryValue* data = new DictionaryValue();
    data->SetString("internal_name", experiment.internal_name);
    data->SetString("name",
                    l10n_util::GetStringUTF16(experiment.visible_name_id));
    data->SetString("description",
                    l10n_util::GetStringUTF16(
                        experiment.visible_description_id));
    data->SetBoolean("enabled",
                      enabled_experiments.count(experiment.internal_name) > 0);

    experiments_data->Append(data);
  }
  return experiments_data;
}

static bool needs_restart_ = false;

bool IsRestartNeededToCommitChanges() {
  return needs_restart_;
}

void SetExperimentEnabled(
    PrefService* prefs, const std::string& internal_name, bool enable) {
  needs_restart_ = true;

  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  if (enable)
    enabled_experiments.insert(internal_name);
  else
    enabled_experiments.erase(internal_name);

  SetEnabledLabs(prefs, enabled_experiments);
}

}  // namespace Labs
<commit_msg>[Mac] Add Instant to labs on Mac.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/labs.h"

#include <algorithm>
#include <iterator>
#include <map>
#include <set>

#include "app/l10n_util.h"
#include "base/command_line.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"

namespace about_labs {

enum { kOsMac = 1 << 0, kOsWin = 1 << 1, kOsLinux = 1 << 2 };

unsigned kOsAll = kOsMac | kOsWin | kOsLinux;

struct Experiment {
  // The internal name of the experiment. This is never shown to the user.
  // It _is_ however stored in the prefs file, so you shouldn't change the
  // name of existing labs.
  const char* internal_name;

  // String id of the message containing the experiment's name.
  int visible_name_id;

  // String id of the message containing the experiment's description.
  int visible_description_id;

  // The platforms the experiment is available on
  // Needs to be more than a compile-time #ifdef because of profile sync.
  unsigned supported_platforms;  // bitmask

  // The commandline parameter that's added when this lab is active. This is
  // different from |internal_name| so that the commandline flag can be
  // renamed without breaking the prefs file.
  const char* command_line;
};

const Experiment kExperiments[] = {
  {
    "expose-for-tabs",  // Do not change; see above.
    IDS_LABS_TABPOSE_NAME,
    IDS_LABS_TABPOSE_DESCRIPTION,
    kOsMac,
#if defined(OS_MACOSX)
    // The switch exists only on OS X.
    switches::kEnableExposeForTabs
#else
    ""
#endif
  },
  {
    "vertical-tabs",  // Do not change; see above.
    IDS_LABS_SIDE_TABS_NAME,
    IDS_LABS_SIDE_TABS_DESCRIPTION,
    kOsWin,
    switches::kEnableVerticalTabs
  },
  {
    "tabbed-options",  // Do not change; see above.
    IDS_LABS_TABBED_OPTIONS_NAME,
    IDS_LABS_TABBED_OPTIONS_DESCRIPTION,
    kOsAll,
    switches::kEnableTabbedOptions
  },
  {
    "remoting",  // Do not change; see above.
    IDS_LABS_REMOTING_NAME,
#if defined(OS_WIN)
    // Windows only supports host functionality at the moment.
    IDS_LABS_REMOTING_HOST_DESCRIPTION,
#elif defined(OS_LINUX)
    // Linux only supports client functionality at the moment.
    IDS_LABS_REMOTING_CLIENT_DESCRIPTION,
#else
    // On other platforms, this lab isn't available at all.
    0,
#endif
    kOsWin | kOsLinux,
    switches::kEnableRemoting
  },
  {
    "disable-outdated-plugins",  // Do not change; see above.
    IDS_LABS_DISABLE_OUTDATED_PLUGINS_NAME,
    IDS_LABS_DISABLE_OUTDATED_PLUGINS_DESCRIPTION,
    kOsAll,
    switches::kDisableOutdatedPlugins
  },
  {
    "xss-auditor",  // Do not change; see above.
    IDS_LABS_XSS_AUDITOR_NAME,
    IDS_LABS_XSS_AUDITOR_DESCRIPTION,
    kOsAll,
    switches::kEnableXSSAuditor
  },
  {
    "background-webapps", // Do not change; see above
    IDS_LABS_BACKGROUND_WEBAPPS_NAME,
    IDS_LABS_BACKGROUND_WEBAPPS_DESCRIPTION,
    kOsAll,
    switches::kEnableBackgroundMode
  },
  {
    "cloud-print-proxy", // Do not change; see above.
    IDS_LABS_CLOUD_PRINT_PROXY_NAME,
    IDS_LABS_CLOUD_PRINT_PROXY_DESCRIPTION,
#if defined(GOOGLE_CHROME_BUILD)
    // For a Chrome build, we know we have a PDF plug-in, and so we'll
    // enable by platform as we get things working.
    0,
#else
    // Otherwise, where we know it could be working if a viable PDF
    // plug-in could be supplied, we'll keep the lab enabled.
    kOsWin,
#endif
    switches::kEnableCloudPrintProxy
  },
  {
    "match-preview",  // Do not change; see above.
    IDS_LABS_INSTANT_NAME,
    IDS_LABS_INSTANT_DESCRIPTION,
    kOsMac,
    switches::kEnableMatchPreview
  },
  // FIXME(scheib): Add Labs entry for accelerated Compositing,
  // or pull it and the strings in generated_resources.grd by Dec 2010
  //{
  //  "gpu-compositing", // Do not change; see above
  //  IDS_LABS_ACCELERATED_COMPOSITING_NAME,
  //  IDS_LABS_ACCELERATED_COMPOSITING_DESCRIPTION,
  //  kOsAll,
  //  switches::kDisableAcceleratedCompositing
  //},
  {
    "gpu-canvas-2d", // Do not change; see above
    IDS_LABS_ACCELERATED_CANVAS_2D_NAME,
    IDS_LABS_ACCELERATED_CANVAS_2D_DESCRIPTION,
    kOsWin | kOsLinux,
    switches::kEnableAccelerated2dCanvas
  }
  // FIXME(scheib): Add Labs entry for WebGL,
  // or pull it and the strings in generated_resources.grd by Dec 2010
  //{
  //  "webgl", // Do not change; see above
  //  IDS_LABS_WEBGL_NAME,
  //  IDS_LABS_WEBGL_DESCRIPTION,
  //  kOsAll,
  //  switches::kDisableExperimentalWebGL
  //}
};

// Extracts the list of enabled lab experiments from preferences and stores them
// in a set.
void GetEnabledLabs(const PrefService* prefs, std::set<std::string>* result) {
  const ListValue* enabled_experiments = prefs->GetList(
      prefs::kEnabledLabsExperiments);
  if (!enabled_experiments)
    return;

  for (ListValue::const_iterator it = enabled_experiments->begin();
       it != enabled_experiments->end();
       ++it) {
    std::string experiment_name;
    if (!(*it)->GetAsString(&experiment_name)) {
      LOG(WARNING) << "Invalid entry in " << prefs::kEnabledLabsExperiments;
      continue;
    }
    result->insert(experiment_name);
  }
}

// Takes a set of enabled lab experiments
void SetEnabledLabs(
    PrefService* prefs, const std::set<std::string>& enabled_experiments) {
  ListValue* experiments_list = prefs->GetMutableList(
      prefs::kEnabledLabsExperiments);
  if (!experiments_list)
    return;

  experiments_list->Clear();
  for (std::set<std::string>::const_iterator it = enabled_experiments.begin();
       it != enabled_experiments.end();
       ++it) {
    experiments_list->Append(new StringValue(*it));
  }
}

// Removes all experiments from prefs::kEnabledLabsExperiments that are
// unknown, to prevent this list to become very long as experiments are added
// and removed.
void SanitizeList(PrefService* prefs) {
  std::set<std::string> known_experiments;
  for (size_t i = 0; i < arraysize(kExperiments); ++i)
    known_experiments.insert(kExperiments[i].internal_name);

  std::set<std::string> enabled_experiments;
  GetEnabledLabs(prefs, &enabled_experiments);

  std::set<std::string> new_enabled_experiments;
  std::set_intersection(
      known_experiments.begin(), known_experiments.end(),
      enabled_experiments.begin(), enabled_experiments.end(),
      std::inserter(new_enabled_experiments, new_enabled_experiments.begin()));

  SetEnabledLabs(prefs, new_enabled_experiments);
}

void GetSanitizedEnabledLabs(
    PrefService* prefs, std::set<std::string>* result) {
  SanitizeList(prefs);
  GetEnabledLabs(prefs, result);
}

int GetCurrentPlatform() {
#if defined(OS_MACOSX)
  return kOsMac;
#elif defined(OS_WIN)
  return kOsWin;
#elif defined(OS_LINUX)
  return kOsLinux;
#else
#error Unknown platform
#endif
}

bool IsEnabled() {
#if defined(OS_CHROMEOS)
  // ChromeOS uses a different mechanism for about:labs; integrated with their
  // dom ui options.
  // TODO(thakis): Port about:labs to chromeos -- http://crbug.com/57634
  return false;
#else
  return true;
#endif
}

void ConvertLabsToSwitches(PrefService* prefs, CommandLine* command_line) {
  if (!IsEnabled())
    return;

  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  std::map<std::string, const Experiment*> experiments;
  for (size_t i = 0; i < arraysize(kExperiments); ++i)
    experiments[kExperiments[i].internal_name] = &kExperiments[i];

  for (std::set<std::string>::iterator it = enabled_experiments.begin();
       it != enabled_experiments.end();
       ++it) {
    const std::string& experiment_name = *it;
    std::map<std::string, const Experiment*>::iterator experiment =
        experiments.find(experiment_name);
    DCHECK(experiment != experiments.end());
    if (experiment == experiments.end())
      continue;

    command_line->AppendSwitch(experiment->second->command_line);
  }
}

ListValue* GetLabsExperimentsData(PrefService* prefs) {
  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  int current_platform = GetCurrentPlatform();

  ListValue* experiments_data = new ListValue();
  for (size_t i = 0; i < arraysize(kExperiments); ++i) {
    const Experiment& experiment = kExperiments[i];
    if (!(experiment.supported_platforms & current_platform))
      continue;

    DictionaryValue* data = new DictionaryValue();
    data->SetString("internal_name", experiment.internal_name);
    data->SetString("name",
                    l10n_util::GetStringUTF16(experiment.visible_name_id));
    data->SetString("description",
                    l10n_util::GetStringUTF16(
                        experiment.visible_description_id));
    data->SetBoolean("enabled",
                      enabled_experiments.count(experiment.internal_name) > 0);

    experiments_data->Append(data);
  }
  return experiments_data;
}

static bool needs_restart_ = false;

bool IsRestartNeededToCommitChanges() {
  return needs_restart_;
}

void SetExperimentEnabled(
    PrefService* prefs, const std::string& internal_name, bool enable) {
  needs_restart_ = true;

  std::set<std::string> enabled_experiments;
  GetSanitizedEnabledLabs(prefs, &enabled_experiments);

  if (enable)
    enabled_experiments.insert(internal_name);
  else
    enabled_experiments.erase(internal_name);

  SetEnabledLabs(prefs, enabled_experiments);
}

}  // namespace Labs
<|endoftext|>


<commit_before>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include <mtp/ptp/Device.h>
#include <mtp/ptp/Response.h>
#include <mtp/ptp/Container.h>
#include <mtp/ptp/Messages.h>
#include <usb/Context.h>
#include <mtp/ptp/OperationRequest.h>

namespace mtp
{

	Device::Device(usb::BulkPipePtr pipe): _packeter(pipe)
	{ }

	SessionPtr Device::OpenSession(u32 sessionId)
	{
		OperationRequest req(OperationCode::OpenSession, 0, sessionId);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		ResponseType code;
		_packeter.Read(0, data, code, response);
		//HexDump("payload", data);

		return std::make_shared<Session>(_packeter.GetPipe(), sessionId);
	}

	DevicePtr Device::Find()
	{
		using namespace mtp;
		usb::ContextPtr ctx(new usb::Context);

		for (usb::DeviceDescriptorPtr desc : ctx->GetDevices())
		{
			usb::DevicePtr device = desc->TryOpen(ctx);
			if (!device)
				continue;
			int confs = desc->GetConfigurationsCount();
			//fprintf(stderr, "configurations: %d\n", confs);

			for(int i = 0; i < confs; ++i)
			{
				usb::ConfigurationPtr conf = desc->GetConfiguration(i);
				int interfaces = conf->GetInterfaceCount();
				//fprintf(stderr, "interfaces: %d\n", interfaces);
				for(int j = 0; j < interfaces; ++j)
				{
					usb::InterfacePtr iface = conf->GetInterface(device, conf, j, 0);
					fprintf(stderr, "%d:%d index %u, eps %u\n", i, j, iface->GetIndex(), iface->GetEndpointsCount());

					ByteArray data(255);
					static const u16 DT_STRING = 3;
					static const u16 DT_INTERFACE = 4;
					device->ReadControl(0x80, 0x06, (DT_STRING << 8) | 0, 0, data, 1000);
					if (data.size() < 4 || data[1] != DT_STRING)
						continue;

					u16 langId = data[2] | ((u16)data[3] << 8);
					data.resize(255);
					std::fill(data.begin(), data.end(), 0xff);
					device->ReadControl(0x80, 0x06, (DT_STRING << 8) | DT_INTERFACE, langId, data, 1000);
					if (data.size() < 4 || data[1] != DT_STRING)
						continue;

					u8 len = data[0];
					InputStream stream(data, 2);
					std::string name = stream.ReadString((len - 2) / 2);
					if (name == "MTP")
					{
						//device->SetConfiguration(configuration->GetIndex());
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
					if (iface->GetClass() == 6 && iface->GetSubclass() == 1)
					{
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
				}
			}
		}

		return nullptr;
	}

}
<commit_msg>removed enumeration logs<commit_after>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * 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 General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include <mtp/ptp/Device.h>
#include <mtp/ptp/Response.h>
#include <mtp/ptp/Container.h>
#include <mtp/ptp/Messages.h>
#include <usb/Context.h>
#include <mtp/ptp/OperationRequest.h>

namespace mtp
{

	Device::Device(usb::BulkPipePtr pipe): _packeter(pipe)
	{ }

	SessionPtr Device::OpenSession(u32 sessionId)
	{
		OperationRequest req(OperationCode::OpenSession, 0, sessionId);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		ResponseType code;
		_packeter.Read(0, data, code, response);
		//HexDump("payload", data);

		return std::make_shared<Session>(_packeter.GetPipe(), sessionId);
	}

	DevicePtr Device::Find()
	{
		using namespace mtp;
		usb::ContextPtr ctx(new usb::Context);

		for (usb::DeviceDescriptorPtr desc : ctx->GetDevices())
		{
			usb::DevicePtr device = desc->TryOpen(ctx);
			if (!device)
				continue;
			int confs = desc->GetConfigurationsCount();
			//fprintf(stderr, "configurations: %d\n", confs);

			for(int i = 0; i < confs; ++i)
			{
				usb::ConfigurationPtr conf = desc->GetConfiguration(i);
				int interfaces = conf->GetInterfaceCount();
				//fprintf(stderr, "interfaces: %d\n", interfaces);
				for(int j = 0; j < interfaces; ++j)
				{
					usb::InterfacePtr iface = conf->GetInterface(device, conf, j, 0);
					//fprintf(stderr, "%d:%d index %u, eps %u\n", i, j, iface->GetIndex(), iface->GetEndpointsCount());

					ByteArray data(255);
					static const u16 DT_STRING = 3;
					static const u16 DT_INTERFACE = 4;
					device->ReadControl(0x80, 0x06, (DT_STRING << 8) | 0, 0, data, 1000);
					if (data.size() < 4 || data[1] != DT_STRING)
						continue;

					u16 langId = data[2] | ((u16)data[3] << 8);
					data.resize(255);
					std::fill(data.begin(), data.end(), 0xff);
					device->ReadControl(0x80, 0x06, (DT_STRING << 8) | DT_INTERFACE, langId, data, 1000);
					if (data.size() < 4 || data[1] != DT_STRING)
						continue;

					u8 len = data[0];
					InputStream stream(data, 2);
					std::string name = stream.ReadString((len - 2) / 2);
					if (name == "MTP")
					{
						//device->SetConfiguration(configuration->GetIndex());
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
					if (iface->GetClass() == 6 && iface->GetSubclass() == 1)
					{
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
				}
			}
		}

		return nullptr;
	}

}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
<commit_msg>Change SEQ timings, SEQ ODT, WC config and DQS polarity<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file workarounds/dp16.C
/// @brief Workarounds for the DP16 logic blocks
/// Workarounds are very deivce specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Steven Glancy <sglancy@usi.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

#include <lib/utils/scom.H>
#include <lib/utils/pos.H>
#include <lib/workarounds/dp16_workarounds.H>

namespace mss
{

namespace workarounds
{

namespace dp16
{

///
/// @brief DQS polarity workaround
/// For Monza DDR port 2, one pair of DQS P/N is swapped polarity.  Not in DDR port 6
/// @param[in] i_target the fapi2 target of the port
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
/// @note This function is called during the phy scom init procedure, after the initfile is
/// processed. It is specific to the Monza module, but can be called for all modules as it
/// will enforce its requirements internally
///
fapi2::ReturnCode dqs_polarity( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
{
    // Receiver config provided by S. Wyatt 8/16
    constexpr uint64_t rx_config = 0x4000;

    // For Monza DDR port 2, one pair of DQS P/N is swapped polarity.  Not in DDR port 6
    // For Monza DDR port 3, one pair of DQS P/N is swapped polarity.  Not in DDR port 7
    const auto l_pos = mss::pos(i_target);

    // TODO RTC:160353 Need module/chip rev EC support for workarounds
    // Need to check this for Monza only when attribute support for EC levels is in place

    // So we need to make sure our position is 2 or 3 and skip for the other ports.
    if (l_pos == 2)
    {
        FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_4, rx_config) );
    }

    if (l_pos == 3)
    {
        FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_0, rx_config) );
    }

fapi_try_exit:
    return fapi2::current_err;
}

} // close namespace dp16
} // close namespace workarounds
} // close namespace mss
<|endoftext|>


<commit_before>// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "deps_format.h"
#include "utils.h"
#include "trace.h"
#include <unordered_set>
#include <tuple>
#include <array>
#include <iterator>
#include <cassert>
#include <functional>

const std::array<const pal::char_t*, deps_entry_t::asset_types::count> deps_json_t::s_known_asset_types = {
    _X("runtime"), _X("resources"), _X("native") };

const deps_entry_t& deps_json_t::try_ni(const deps_entry_t& entry) const
{
    if (m_ni_entries.count(entry.asset_name))
    {
        int index = m_ni_entries.at(entry.asset_name);
        return m_deps_entries[deps_entry_t::asset_types::runtime][index];
    }
    return entry;
}

void deps_json_t::reconcile_libraries_with_targets(
    const json_value& json,
    const std::function<bool(const pal::string_t&)>& library_exists_fn,
    const std::function<const std::vector<pal::string_t>&(const pal::string_t&, int)>& get_rel_paths_by_asset_type_fn)
{
    const auto& libraries = json.at(_X("libraries")).as_object();
    for (const auto& library : libraries)
    {
        trace::info(_X("Reconciling library %s"), library.first.c_str());

        if (pal::to_lower(library.second.at(_X("type")).as_string()) != _X("package"))
        {
            trace::info(_X("Library %s is not a package"), library.first.c_str());
            continue;
        }
        if (!library_exists_fn(library.first))
        {
            trace::info(_X("Library %s does not exist"), library.first.c_str());
            continue;
        }

        const auto& properties = library.second.as_object();

        const pal::string_t& hash = properties.at(_X("sha512")).as_string();
        bool serviceable = properties.at(_X("serviceable")).as_bool();

        for (int i = 0; i < s_known_asset_types.size(); ++i)
        {
            for (const auto& rel_path : get_rel_paths_by_asset_type_fn(library.first, i))
            {
                bool ni_dll = false;
                auto asset_name = get_filename_without_ext(rel_path);
                if (ends_with(asset_name, _X(".ni"), false))
                {
                    ni_dll = true;
                    asset_name = strip_file_ext(asset_name);
                }

                deps_entry_t entry;
                size_t pos = library.first.find(_X("/"));
                entry.library_name = library.first.substr(0, pos);
                entry.library_version = library.first.substr(pos + 1);
                entry.library_type = _X("package");
                entry.library_hash = hash;
                entry.asset_name = asset_name;
                entry.asset_type = s_known_asset_types[i];
                entry.relative_path = rel_path;
                entry.is_serviceable = serviceable;

                // TODO: Deps file does not follow spec. It uses '\\', should use '/'
                replace_char(&entry.relative_path, _X('\\'), _X('/'));

                m_deps_entries[i].push_back(entry);

                if (ni_dll)
                {
                    m_ni_entries[entry.asset_name] = m_deps_entries
                        [deps_entry_t::asset_types::runtime].size() - 1;
                }

                trace::info(_X("Added %s %s deps entry [%d] [%s, %s, %s]"), s_known_asset_types[i], entry.asset_name.c_str(), m_deps_entries[i].size() - 1, entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str());

                if (i == deps_entry_t::asset_types::native &&
                    entry.asset_name == LIBCORECLR_FILENAME)
                {
                    m_coreclr_index = m_deps_entries[i].size() - 1;
                    trace::verbose(_X("Found coreclr from deps %d [%s, %s, %s]"),
                        m_coreclr_index,
                        entry.library_name.c_str(),
                        entry.library_version.c_str(),
                        entry.relative_path.c_str());
                }

            }
        }
    }
}

pal::string_t get_own_rid()
{
#define _STRINGIFY(s) _X(s)
#if defined(TARGET_RUNTIME_ID)
    return _STRINGIFY(TARGET_RUNTIME_ID);
#else
#error "Cannot build the host without knowing host's root RID"
#endif
}

bool deps_json_t::perform_rid_fallback(rid_specific_assets_t* portable_assets, const rid_fallback_graph_t& rid_fallback_graph)
{
    pal::string_t host_rid = get_own_rid();
    for (auto& package : *portable_assets)
    {
        pal::string_t matched_rid = package.second.count(host_rid) ? host_rid : _X("");
        if (matched_rid.empty())
        {
            if (rid_fallback_graph.count(host_rid) == 0)
            {
                trace::error(_X("Did not find fallback rids for package %s for the host rid %s"), package.first.c_str(), host_rid.c_str());
                return false;
            }
            const auto& fallback_rids = rid_fallback_graph.find(host_rid)->second;
            auto iter = std::find_if(fallback_rids.begin(), fallback_rids.end(), [&package](const pal::string_t& rid) {
                return package.second.count(rid);
            });
            if (iter == fallback_rids.end() || (*iter).empty())
            {
                trace::error(_X("Did not find a matching fallback rid for package %s for the host rid %s"), package.first.c_str(), host_rid.c_str());
                return false;
            }
            matched_rid = *iter;
        }
        assert(!matched_rid.empty());
        for (auto iter = package.second.begin(); iter != package.second.end(); /* */)
        {
            if (iter->first != matched_rid)
            {
                 iter = package.second.erase(iter);
            }
            else
            {
                 ++iter;
            }
        }
    }
    return true;
}

bool deps_json_t::process_runtime_targets(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph, rid_specific_assets_t* p_assets)
{
    rid_specific_assets_t& assets = *p_assets;
    for (const auto& package : json.at(_X("targets")).at(target_name).as_object())
    {
        const auto& targets = package.second.as_object();
        auto iter = targets.find(_X("runtimeTargets"));
        if (iter == targets.end())
        {
            continue;
        }

        const auto& files = iter->second.as_object();
        for (const auto& file : files)
        {
            const auto& type = file.second.at(_X("assetType")).as_string();
            for (int i = 0; i < s_known_asset_types.size(); ++i)
            {
                if (pal::strcasecmp(type.c_str(), s_known_asset_types[i]) == 0)
                {
                    const auto& rid = file.second.at(_X("rid")).as_string();
                    assets[package.first][rid][i].push_back(file.first);
                }
            }
        }
    }

    if (!perform_rid_fallback(&assets, rid_fallback_graph))
    {
        return false;
    }

    return true;
}

bool deps_json_t::process_targets(const json_value& json, const pal::string_t& target_name, deps_assets_t* p_assets)
{
    deps_assets_t& assets = *p_assets;
    for (const auto& package : json.at(_X("targets")).at(target_name).as_object())
    {
        // if (package.second.at(_X("type")).as_string() != _X("package")) continue;

        const auto& asset_types = package.second.as_object();
        for (int i = 0; i < s_known_asset_types.size(); ++i)
        {
            auto iter = asset_types.find(s_known_asset_types[i]);
            if (iter != asset_types.end())
            {
                for (const auto& file : iter->second.as_object())
                {
                    trace::info(_X("Adding %s asset %s from %s"), s_known_asset_types[i], file.first.c_str(), package.first.c_str());
                    assets[package.first][i].push_back(file.first);
                }
            }
        }
    }
    return true;
}

bool deps_json_t::load_portable(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph)
{
    rid_specific_assets_t rid_assets;
    if (!process_runtime_targets(json, target_name, rid_fallback_graph, &rid_assets))
    {
        return false;
    }

    deps_assets_t non_rid_assets;
    if (!process_targets(json, target_name, &non_rid_assets))
    {
        return false;
    }

    std::vector<pal::string_t> merged;
    auto package_exists = [&rid_assets, &non_rid_assets](const pal::string_t& package) -> bool {
        return rid_assets.count(package) || non_rid_assets.count(package);
    };
    auto get_relpaths = [&rid_assets, &non_rid_assets, &merged](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {
        if (rid_assets.count(package) && non_rid_assets.count(package))
        {
            const std::vector<pal::string_t>& rel1 = rid_assets[package].begin()->second[type_index];
            const std::vector<pal::string_t>& rel2 = non_rid_assets[package][type_index];
            merged.clear();
            merged.reserve(rel1.size() + rel2.size());
            merged.insert(merged.end(), rel1.begin(), rel1.end());
            merged.insert(merged.end(), rel2.begin(), rel2.end());
            return merged;
        }
        else
        {
            return rid_assets.count(package)
                ? rid_assets[package].begin()->second[type_index]
                : non_rid_assets[package][type_index];
        }
    };

    reconcile_libraries_with_targets(json, package_exists, get_relpaths);

    return true;
}

bool deps_json_t::load_standalone(const json_value& json, const pal::string_t& target_name)
{
    deps_assets_t assets;

    if (!process_targets(json, target_name, &assets))
    {
        return false;
    }

    auto package_exists = [&assets](const pal::string_t& package) -> bool {
        return assets.count(package);
    };

    auto get_relpaths = [&assets](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {
        return assets[package][type_index];
    };

    reconcile_libraries_with_targets(json, package_exists, get_relpaths);

    const auto& json_object = json.as_object();
    const auto iter = json_object.find(_X("runtimes"));
    if (iter != json_object.end())
    {
        for (const auto& rid : iter->second.as_object())
        {
            auto& vec = m_rid_fallback_graph[rid.first];
            for (const auto& fallback : rid.second.as_array())
            {
                vec.push_back(fallback.as_string());
            }
        }
    }
    return true;
}

// -----------------------------------------------------------------------------
// Load the deps file and parse its "entry" lines which contain the "fields" of
// the entry. Populate an array of these entries.
//
bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
{
    // If file doesn't exist, then assume parsed.
    if (!pal::file_exists(deps_path))
    {
        return true;
    }

    // Somehow the file stream could not be opened. This is an error.
    pal::ifstream_t file(deps_path);
    if (!file.good())
    {
        return false;
    }

    try
    {
        const auto json = json_value::parse(file);

        const auto& runtime_target = json.at(_X("runtimeTarget"));
        const pal::string_t& name = runtime_target.as_string();

        return (portable) ? load_portable(json, name, rid_fallback_graph) : load_standalone(json, name);
    }
    catch (...)
    {
        return false;
    }
}
<commit_msg>Revert merging relpaths and relax erroring<commit_after>// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "deps_format.h"
#include "utils.h"
#include "trace.h"
#include <unordered_set>
#include <tuple>
#include <array>
#include <iterator>
#include <cassert>
#include <functional>

const std::array<const pal::char_t*, deps_entry_t::asset_types::count> deps_json_t::s_known_asset_types = {
    _X("runtime"), _X("resources"), _X("native") };

const deps_entry_t& deps_json_t::try_ni(const deps_entry_t& entry) const
{
    if (m_ni_entries.count(entry.asset_name))
    {
        int index = m_ni_entries.at(entry.asset_name);
        return m_deps_entries[deps_entry_t::asset_types::runtime][index];
    }
    return entry;
}

void deps_json_t::reconcile_libraries_with_targets(
    const json_value& json,
    const std::function<bool(const pal::string_t&)>& library_exists_fn,
    const std::function<const std::vector<pal::string_t>&(const pal::string_t&, int)>& get_rel_paths_by_asset_type_fn)
{
    const auto& libraries = json.at(_X("libraries")).as_object();
    for (const auto& library : libraries)
    {
        trace::info(_X("Reconciling library %s"), library.first.c_str());

        if (pal::to_lower(library.second.at(_X("type")).as_string()) != _X("package"))
        {
            trace::info(_X("Library %s is not a package"), library.first.c_str());
            continue;
        }
        if (!library_exists_fn(library.first))
        {
            trace::info(_X("Library %s does not exist"), library.first.c_str());
            continue;
        }

        const auto& properties = library.second.as_object();

        const pal::string_t& hash = properties.at(_X("sha512")).as_string();
        bool serviceable = properties.at(_X("serviceable")).as_bool();

        for (int i = 0; i < s_known_asset_types.size(); ++i)
        {
            for (const auto& rel_path : get_rel_paths_by_asset_type_fn(library.first, i))
            {
                bool ni_dll = false;
                auto asset_name = get_filename_without_ext(rel_path);
                if (ends_with(asset_name, _X(".ni"), false))
                {
                    ni_dll = true;
                    asset_name = strip_file_ext(asset_name);
                }

                deps_entry_t entry;
                size_t pos = library.first.find(_X("/"));
                entry.library_name = library.first.substr(0, pos);
                entry.library_version = library.first.substr(pos + 1);
                entry.library_type = _X("package");
                entry.library_hash = hash;
                entry.asset_name = asset_name;
                entry.asset_type = s_known_asset_types[i];
                entry.relative_path = rel_path;
                entry.is_serviceable = serviceable;

                // TODO: Deps file does not follow spec. It uses '\\', should use '/'
                replace_char(&entry.relative_path, _X('\\'), _X('/'));

                m_deps_entries[i].push_back(entry);

                if (ni_dll)
                {
                    m_ni_entries[entry.asset_name] = m_deps_entries
                        [deps_entry_t::asset_types::runtime].size() - 1;
                }

                trace::info(_X("Added %s %s deps entry [%d] [%s, %s, %s]"), s_known_asset_types[i], entry.asset_name.c_str(), m_deps_entries[i].size() - 1, entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str());

                if (i == deps_entry_t::asset_types::native &&
                    entry.asset_name == LIBCORECLR_FILENAME)
                {
                    m_coreclr_index = m_deps_entries[i].size() - 1;
                    trace::verbose(_X("Found coreclr from deps %d [%s, %s, %s]"),
                        m_coreclr_index,
                        entry.library_name.c_str(),
                        entry.library_version.c_str(),
                        entry.relative_path.c_str());
                }

            }
        }
    }
}

pal::string_t get_own_rid()
{
#define _STRINGIFY(s) _X(s)
#if defined(TARGET_RUNTIME_ID)
    return _STRINGIFY(TARGET_RUNTIME_ID);
#else
#error "Cannot build the host without knowing host's root RID"
#endif
}

bool deps_json_t::perform_rid_fallback(rid_specific_assets_t* portable_assets, const rid_fallback_graph_t& rid_fallback_graph)
{
    pal::string_t host_rid = get_own_rid();
    for (auto& package : *portable_assets)
    {
        pal::string_t matched_rid = package.second.count(host_rid) ? host_rid : _X("");
        if (matched_rid.empty())
        {
            if (rid_fallback_graph.count(host_rid) == 0)
            {
                trace::error(_X("Did not find fallback rids for package %s for the host rid %s"), package.first.c_str(), host_rid.c_str());
                return false;
            }
            const auto& fallback_rids = rid_fallback_graph.find(host_rid)->second;
            auto iter = std::find_if(fallback_rids.begin(), fallback_rids.end(), [&package](const pal::string_t& rid) {
                return package.second.count(rid);
            });
            if (iter != fallback_rids.end())
            {
                matched_rid = *iter;
            }
        }

        if (matched_rid.empty())
        {
            package.second.clear();
        }

        for (auto iter = package.second.begin(); iter != package.second.end(); /* */)
        {
            if (iter->first != matched_rid)
            {
                trace::verbose(_X("Chose %s, so removing rid (%s) specific assets for package %s"), matched_rid.c_str(), iter->first.c_str(), package.first.c_str());
                iter = package.second.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
    }
    return true;
}

bool deps_json_t::process_runtime_targets(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph, rid_specific_assets_t* p_assets)
{
    rid_specific_assets_t& assets = *p_assets;
    for (const auto& package : json.at(_X("targets")).at(target_name).as_object())
    {
        const auto& targets = package.second.as_object();
        auto iter = targets.find(_X("runtimeTargets"));
        if (iter == targets.end())
        {
            continue;
        }

        const auto& files = iter->second.as_object();
        for (const auto& file : files)
        {
            const auto& type = file.second.at(_X("assetType")).as_string();
            for (int i = 0; i < s_known_asset_types.size(); ++i)
            {
                if (pal::strcasecmp(type.c_str(), s_known_asset_types[i]) == 0)
                {
                    const auto& rid = file.second.at(_X("rid")).as_string();
                    assets[package.first][rid][i].push_back(file.first);
                }
            }
        }
    }

    if (!perform_rid_fallback(&assets, rid_fallback_graph))
    {
        return false;
    }

    return true;
}

bool deps_json_t::process_targets(const json_value& json, const pal::string_t& target_name, deps_assets_t* p_assets)
{
    deps_assets_t& assets = *p_assets;
    for (const auto& package : json.at(_X("targets")).at(target_name).as_object())
    {
        // if (package.second.at(_X("type")).as_string() != _X("package")) continue;
        const auto& asset_types = package.second.as_object();
        for (int i = 0; i < s_known_asset_types.size(); ++i)
        {
            auto iter = asset_types.find(s_known_asset_types[i]);
            if (iter != asset_types.end())
            {
                for (const auto& file : iter->second.as_object())
                {
                    trace::info(_X("Adding %s asset %s from %s"), s_known_asset_types[i], file.first.c_str(), package.first.c_str());
                    assets[package.first][i].push_back(file.first);
                }
            }
        }
    }
    return true;
}

bool deps_json_t::load_portable(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph)
{
    rid_specific_assets_t rid_assets;
    if (!process_runtime_targets(json, target_name, rid_fallback_graph, &rid_assets))
    {
        return false;
    }

    deps_assets_t non_rid_assets;
    if (!process_targets(json, target_name, &non_rid_assets))
    {
        return false;
    }

    auto package_exists = [&rid_assets, &non_rid_assets](const pal::string_t& package) -> bool {
        return rid_assets.count(package) || non_rid_assets.count(package);
    };
    auto get_relpaths = [&rid_assets, &non_rid_assets](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {

        // Is there any rid specific assets for this type ("native" or "runtime" or "resources")
        if (rid_assets.count(package) && !rid_assets[package].empty())
        {
            const auto& assets_by_type = rid_assets[package].begin()->second[type_index];
            if (!assets_by_type.empty())
            {
                return assets_by_type;
            }

            trace::verbose(_X("There were no rid specific %s asset for %s"), deps_json_t::s_known_asset_types[type_index], package.c_str());
        }

        return non_rid_assets[package][type_index];
    };

    reconcile_libraries_with_targets(json, package_exists, get_relpaths);

    return true;
}

bool deps_json_t::load_standalone(const json_value& json, const pal::string_t& target_name)
{
    deps_assets_t assets;

    if (!process_targets(json, target_name, &assets))
    {
        return false;
    }

    auto package_exists = [&assets](const pal::string_t& package) -> bool {
        return assets.count(package);
    };

    auto get_relpaths = [&assets](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {
        return assets[package][type_index];
    };

    reconcile_libraries_with_targets(json, package_exists, get_relpaths);

    const auto& json_object = json.as_object();
    const auto iter = json_object.find(_X("runtimes"));
    if (iter != json_object.end())
    {
        for (const auto& rid : iter->second.as_object())
        {
            auto& vec = m_rid_fallback_graph[rid.first];
            for (const auto& fallback : rid.second.as_array())
            {
                vec.push_back(fallback.as_string());
            }
        }
    }
    return true;
}

// -----------------------------------------------------------------------------
// Load the deps file and parse its "entry" lines which contain the "fields" of
// the entry. Populate an array of these entries.
//
bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
{
    // If file doesn't exist, then assume parsed.
    if (!pal::file_exists(deps_path))
    {
        return true;
    }

    // Somehow the file stream could not be opened. This is an error.
    pal::ifstream_t file(deps_path);
    if (!file.good())
    {
        return false;
    }

    try
    {
        const auto json = json_value::parse(file);

        const auto& runtime_target = json.at(_X("runtimeTarget"));
        const pal::string_t& name = runtime_target.as_string();

        return (portable) ? load_portable(json, name, rid_fallback_graph) : load_standalone(json, name);
    }
    catch (...)
    {
        return false;
    }
}
<|endoftext|>


<commit_before>#include <boost/asio/io_service.hpp>
#include <silicium/connecting_observable.hpp>
#include <silicium/total_consumer.hpp>
#include <silicium/http/http.hpp>
#include <silicium/coroutine.hpp>
#include <silicium/sending_observable.hpp>
#include <silicium/socket_observable.hpp>
#include <iostream>

namespace
{
	Si::http::request_header make_get_request(std::string host, std::string path)
	{
		Si::http::request_header header;
		header.http_version = "HTTP/1.0";
		header.method = "GET";
		header.path = std::move(path);
		header.arguments["Host"] = std::move(host);
		return header;
	}
}

int main()
{
	boost::asio::io_service io;
	boost::asio::ip::tcp::socket socket(io);
	Si::connecting_observable connector(socket, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), 8080));
	auto connecting = Si::make_total_consumer(Si::make_coroutine<Si::nothing>([&connector, &socket](Si::yield_context<Si::nothing> &yield) -> void
	{
		{
			boost::optional<boost::system::error_code> const error = yield.get_one(connector);
			assert(error);
			if (*error)
			{
				return;
			}
		}

		{
			std::vector<char> send_buffer;
			auto send_sink = Si::make_container_sink(send_buffer);
			Si::http::write_header(send_sink, make_get_request("localhost", "/0cf58519be5d78070b76de0549279ef7d7d29a29bd46fd3b530baf962b40430a"));
			Si::sending_observable sending(socket, boost::make_iterator_range(send_buffer.data(), send_buffer.data() + send_buffer.size()));
			boost::optional<Si::error_or<std::size_t>> const error = yield.get_one(sending);
			assert(error);
			if (error->is_error())
			{
				return;
			}
		}

		for (;;)
		{
			std::array<char, 4096> receive_buffer;
			Si::socket_observable receiving(socket, boost::make_iterator_range(receive_buffer.data(), receive_buffer.data() + receive_buffer.size()));
			boost::optional<Si::received_from_socket> const received = yield.get_one(receiving);
			if (!received)
			{
				break;
			}
			if (received->is_error())
			{
				break;
			}
			Si::incoming_bytes const &bytes = received->get();
			std::cout.write(bytes.begin, std::distance(bytes.begin, bytes.end));
		}
	}));
	connecting.start();
	io.run();
}
<commit_msg>actually parse the response header<commit_after>#include <boost/asio/io_service.hpp>
#include <silicium/connecting_observable.hpp>
#include <silicium/total_consumer.hpp>
#include <silicium/http/http.hpp>
#include <silicium/coroutine.hpp>
#include <silicium/sending_observable.hpp>
#include <silicium/socket_observable.hpp>
#include <silicium/received_from_socket_source.hpp>
#include <silicium/observable_source.hpp>
#include <iostream>

namespace
{
	Si::http::request_header make_get_request(std::string host, std::string path)
	{
		Si::http::request_header header;
		header.http_version = "HTTP/1.0";
		header.method = "GET";
		header.path = std::move(path);
		header.arguments["Host"] = std::move(host);
		return header;
	}
}

int main()
{
	boost::asio::io_service io;
	boost::asio::ip::tcp::socket socket(io);
	Si::connecting_observable connector(socket, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), 8080));
	auto connecting = Si::make_total_consumer(Si::make_coroutine<Si::nothing>([&connector, &socket](Si::yield_context<Si::nothing> &yield) -> void
	{
		{
			boost::optional<boost::system::error_code> const error = yield.get_one(connector);
			assert(error);
			if (*error)
			{
				return;
			}
		}

		{
			std::vector<char> send_buffer;
			auto send_sink = Si::make_container_sink(send_buffer);
			Si::http::write_header(send_sink, make_get_request("localhost", "/0cf58519be5d78070b76de0549279ef7d7d29a29bd46fd3b530baf962b40430a"));
			Si::sending_observable sending(socket, boost::make_iterator_range(send_buffer.data(), send_buffer.data() + send_buffer.size()));
			boost::optional<Si::error_or<std::size_t>> const error = yield.get_one(sending);
			assert(error);
			if (error->is_error())
			{
				return;
			}
		}

		{
			std::array<char, 4096> receive_buffer;
			auto socket_source = Si::make_observable_source(Si::socket_observable(socket, boost::make_iterator_range(receive_buffer.data(), receive_buffer.data() + receive_buffer.size())), yield);
			{
				Si::received_from_socket_source response_source(socket_source);
				boost::optional<Si::http::response_header> const response = Si::http::parse_response_header(response_source);
				if (!response)
				{
					return;
				}
			}
			for (;;)
			{
				auto piece = Si::get(socket_source);
				if (!piece || piece->is_error())
				{
					break;
				}
				auto const &bytes = piece->get();
				std::cout.write(bytes.begin, std::distance(bytes.begin, bytes.end));
			}
		}
	}));
	connecting.start();
	io.run();
}
<|endoftext|>