<commit_before>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

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

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "raptor.h"
#include "type/data.h"
#include "utils/timer.h"
#include <boost/program_options.hpp>
#include <boost/progress.hpp>
#include <random>
#include <fstream>
#include "utils/init.h"
#include "utils/csv.h"

using namespace navitia;
using namespace routing;
namespace po = boost::program_options;

struct PathDemand {
    type::idx_t start;
    type::idx_t target;
    unsigned int date;
    unsigned int hour;
};

struct Result {
    int duration;
    int time;
    int arrival;
    int nb_changes;

    Result(Path path) : duration(path.duration.total_seconds()), time(-1), arrival(-1), nb_changes(path.nb_changes) {
        if(!path.items.empty())
            arrival = path.items.back().arrival.time_of_day().total_seconds();
    }
};

int main(int argc, char** argv){
    navitia::init_app();
    po::options_description desc("Options de l'outil de benchmark");
    std::string file, output, stop_input_file;
    int iterations, start, target, date, hour;

    desc.add_options()
            ("help", "Show this message")
            ("interations,i", po::value<int>(&iterations)->default_value(100),
                     "Number of iterations (10 calcuations par iteration)")
            ("file,f", po::value<std::string>(&file)->default_value("data.nav.lz4"),
                     "Path to data.nav.lz4")
            ("start,s", po::value<int>(&start)->default_value(-1),
                    "Start of a particular journey")
            ("target,t", po::value<int>(&target)->default_value(-1),
                    "Target of a particular journey")
            ("date,d", po::value<int>(&date)->default_value(-1),
                    "Begginning date of a particular journey")
            ("hour,h", po::value<int>(&hour)->default_value(-1),
                    "Begginning hour of a particular journey")
            ("verbose,v", "Verbose debugging output")
            ("stop_files", po::value<std::string>(&stop_input_file), "File with list of start and target")
            ("output,o", po::value<std::string>(&output)->default_value("benchmark.csv"),
                     "Output file");
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
    bool verbose = vm.count("verbose");

    if (vm.count("help")) {
        std::cout << "This is used to benchmark journey computation" << std::endl;
        std::cout << desc << std::endl;
        return 1;
    }

    type::Data data;
    {
        Timer t("Chargement des données : " + file);
        data.load(file);
    }
    std::vector<PathDemand> demands;

    if (! stop_input_file.empty()) {
        //csv file should be the same as the output one
        CsvReader csv(stop_input_file, ',');
        csv.next();
        size_t cpt_not_found = 0;
        for (auto it = csv.next(); ! csv.eof(); it = csv.next()) {
            const auto it_start = data.pt_data->stop_areas_map.find(it[0]);
            if (it_start == data.pt_data->stop_areas_map.end()) {
                std::cout << "impossible to find " << it[0] << std::endl;
                cpt_not_found++;
                continue;
            }
            const auto start = it_start->second;

            const auto it_end = data.pt_data->stop_areas_map.find(it[2]);
            if (it_end == data.pt_data->stop_areas_map.end()) {
                std::cout << "impossible to find " << it[2] << std::endl;
                cpt_not_found++;
                continue;
            }
            const auto end = it_end->second;

            PathDemand demand;
            demand.start = start->idx;
            demand.target = end->idx;
            demand.hour = boost::lexical_cast<unsigned int>(it[5]);
            demand.date = boost::lexical_cast<unsigned int>(it[4]);
            demands.push_back(demand);
        }
        std::cout << "nb start not found " << cpt_not_found << std::endl;
    }
    else if(start != -1 && target != -1 && date != -1 && hour != -1) {
        PathDemand demand;
        demand.start = start;
        demand.target = target;
        demand.hour = hour;
        demand.date = date;
        demands.push_back(demand);
    } else {
        // Génération des instances
        std::random_device rd;
        std::mt19937 rng(31442);
        std::uniform_int_distribution<> gen(0,data.pt_data->stop_areas.size()-1);
        std::vector<unsigned int> hours{0, 28800, 36000, 72000, 86000};
        std::vector<unsigned int> days({7});
        if(data.pt_data->validity_patterns.front()->beginning_date.day_of_week().as_number() == 6)
            days.push_back(8);
        else
            days.push_back(13);

        for(int i = 0; i < iterations; ++i) {
            PathDemand demand;
            demand.start = gen(rng);
            demand.target = gen(rng);
            while(demand.start == demand.target) {
                demand.target = gen(rng);
                demand.start = gen(rng);
            }
            for(auto day : days) {
                for(auto hour : hours) {
                    demand.date = day;
                    demand.hour = hour;
                    demands.push_back(demand);
                }
            }
        }
    }

    // Calculs des itinéraires
    std::vector<Result> results;
    data.build_raptor();
    RAPTOR router(data);

    std::cout << "On lance le benchmark de l'algo " << std::endl;
    boost::progress_display show_progress(demands.size());
    Timer t("Calcul avec l'algorithme ");
    //ProfilerStart("bench.prof");
    int nb_reponses = 0;
    for(auto demand : demands){
        ++show_progress;
        Timer t2;
        if (verbose){
            std::cout << data.pt_data->stop_areas[demand.start]->uri
                      << ", " << demand.start
                      << ", " << data.pt_data->stop_areas[demand.target]->uri
                      << ", " << demand.target
                      << ", " << demand.date
                      << ", " << demand.hour
                      << "\n";
        }
        auto res = router.compute(data.pt_data->stop_areas[demand.start], data.pt_data->stop_areas[demand.target], demand.hour, demand.date, DateTimeUtils::set(demand.date + 1, demand.hour),false, true);

        Path path;
        if(res.size() > 0) {
            path = res[0];
            ++ nb_reponses;
        }

        Result result(path);
        result.time = t2.ms();
        results.push_back(result);
    }
    //ProfilerStop();

    Timer ecriture("Writing results");
    std::fstream out_file(output, std::ios::out);
    out_file << "Start, Start id, Target, Target id, Day, Hour";
        out_file << ", "
                 << "arrival, "
                 << "duration, "
                 << "nb_change, "
                 << "visited, "
                 << "time";
    out_file << "\n";

    for(size_t i = 0; i < demands.size(); ++i){
        PathDemand demand = demands[i];
        out_file << data.pt_data->stop_areas[demand.start]->uri
                 << ", " << demand.start
                 << ", " << data.pt_data->stop_areas[demand.target]->uri
                 << ", " << demand.target
                 << ", " << demand.date
                 << ", " << demand.hour;

        out_file << ", "
                 << results[i].arrival << ", "
                 << results[i].duration << ", "
                 << results[i].nb_changes << ", "
                 << results[i].time;

        out_file << "\n";
    }
    out_file.close();

    std::cout << "Number of requests: " << demands.size() << std::endl;
    std::cout << "Number of results with solution: " << nb_reponses << std::endl;
}
<commit_msg>Bench: add callgrind instruction<commit_after>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

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

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "raptor.h"
#include "type/data.h"
#include "utils/timer.h"
#include <boost/program_options.hpp>
#include <boost/progress.hpp>
#include <random>
#include <fstream>
#include "utils/init.h"
#include "utils/csv.h"
#ifdef __BENCH_WITH_CALGRIND__
#include "valgrind/callgrind.h"
#endif

using namespace navitia;
using namespace routing;
namespace po = boost::program_options;

struct PathDemand {
    type::idx_t start;
    type::idx_t target;
    unsigned int date;
    unsigned int hour;
};

struct Result {
    int duration;
    int time;
    int arrival;
    int nb_changes;

    Result(Path path) : duration(path.duration.total_seconds()), time(-1), arrival(-1), nb_changes(path.nb_changes) {
        if(!path.items.empty())
            arrival = path.items.back().arrival.time_of_day().total_seconds();
    }
};

int main(int argc, char** argv){
    navitia::init_app();
    po::options_description desc("Options de l'outil de benchmark");
    std::string file, output, stop_input_file;
    int iterations, start, target, date, hour;

    desc.add_options()
            ("help", "Show this message")
            ("interations,i", po::value<int>(&iterations)->default_value(100),
                     "Number of iterations (10 calcuations par iteration)")
            ("file,f", po::value<std::string>(&file)->default_value("data.nav.lz4"),
                     "Path to data.nav.lz4")
            ("start,s", po::value<int>(&start)->default_value(-1),
                    "Start of a particular journey")
            ("target,t", po::value<int>(&target)->default_value(-1),
                    "Target of a particular journey")
            ("date,d", po::value<int>(&date)->default_value(-1),
                    "Begginning date of a particular journey")
            ("hour,h", po::value<int>(&hour)->default_value(-1),
                    "Begginning hour of a particular journey")
            ("verbose,v", "Verbose debugging output")
            ("stop_files", po::value<std::string>(&stop_input_file), "File with list of start and target")
            ("output,o", po::value<std::string>(&output)->default_value("benchmark.csv"),
                     "Output file");
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
    bool verbose = vm.count("verbose");

    if (vm.count("help")) {
        std::cout << "This is used to benchmark journey computation" << std::endl;
        std::cout << desc << std::endl;
        return 1;
    }

    type::Data data;
    {
        Timer t("Chargement des données : " + file);
        data.load(file);
    }
    std::vector<PathDemand> demands;

    if (! stop_input_file.empty()) {
        //csv file should be the same as the output one
        CsvReader csv(stop_input_file, ',');
        csv.next();
        size_t cpt_not_found = 0;
        for (auto it = csv.next(); ! csv.eof(); it = csv.next()) {
            const auto it_start = data.pt_data->stop_areas_map.find(it[0]);
            if (it_start == data.pt_data->stop_areas_map.end()) {
                std::cout << "impossible to find " << it[0] << std::endl;
                cpt_not_found++;
                continue;
            }
            const auto start = it_start->second;

            const auto it_end = data.pt_data->stop_areas_map.find(it[2]);
            if (it_end == data.pt_data->stop_areas_map.end()) {
                std::cout << "impossible to find " << it[2] << std::endl;
                cpt_not_found++;
                continue;
            }
            const auto end = it_end->second;

            PathDemand demand;
            demand.start = start->idx;
            demand.target = end->idx;
            demand.hour = boost::lexical_cast<unsigned int>(it[5]);
            demand.date = boost::lexical_cast<unsigned int>(it[4]);
            demands.push_back(demand);
        }
        std::cout << "nb start not found " << cpt_not_found << std::endl;
    }
    else if(start != -1 && target != -1 && date != -1 && hour != -1) {
        PathDemand demand;
        demand.start = start;
        demand.target = target;
        demand.hour = hour;
        demand.date = date;
        demands.push_back(demand);
    } else {
        // Génération des instances
        std::random_device rd;
        std::mt19937 rng(31442);
        std::uniform_int_distribution<> gen(0,data.pt_data->stop_areas.size()-1);
        std::vector<unsigned int> hours{0, 28800, 36000, 72000, 86000};
        std::vector<unsigned int> days({7});
        if(data.pt_data->validity_patterns.front()->beginning_date.day_of_week().as_number() == 6)
            days.push_back(8);
        else
            days.push_back(13);

        for(int i = 0; i < iterations; ++i) {
            PathDemand demand;
            demand.start = gen(rng);
            demand.target = gen(rng);
            while(demand.start == demand.target) {
                demand.target = gen(rng);
                demand.start = gen(rng);
            }
            for(auto day : days) {
                for(auto hour : hours) {
                    demand.date = day;
                    demand.hour = hour;
                    demands.push_back(demand);
                }
            }
        }
    }

    // Calculs des itinéraires
    std::vector<Result> results;
    data.build_raptor();
    RAPTOR router(data);

    std::cout << "On lance le benchmark de l'algo " << std::endl;
    boost::progress_display show_progress(demands.size());
    Timer t("Calcul avec l'algorithme ");
    //ProfilerStart("bench.prof");
    int nb_reponses = 0;
#ifdef __BENCH_WITH_CALGRIND__
    CALLGRIND_START_INSTRUMENTATION;
#endif
    for(auto demand : demands){
        ++show_progress;
        Timer t2;
        if (verbose){
            std::cout << data.pt_data->stop_areas[demand.start]->uri
                      << ", " << demand.start
                      << ", " << data.pt_data->stop_areas[demand.target]->uri
                      << ", " << demand.target
                      << ", " << demand.date
                      << ", " << demand.hour
                      << "\n";
        }
        auto res = router.compute(data.pt_data->stop_areas[demand.start], data.pt_data->stop_areas[demand.target], demand.hour, demand.date, DateTimeUtils::set(demand.date + 1, demand.hour),false, true);

        Path path;
        if(res.size() > 0) {
            path = res[0];
            ++ nb_reponses;
        }

        Result result(path);
        result.time = t2.ms();
        results.push_back(result);
    }
    //ProfilerStop();
#ifdef __BENCH_WITH_CALGRIND__
    CALLGRIND_STOP_INSTRUMENTATION;
#endif

    Timer ecriture("Writing results");
    std::fstream out_file(output, std::ios::out);
    out_file << "Start, Start id, Target, Target id, Day, Hour";
        out_file << ", "
                 << "arrival, "
                 << "duration, "
                 << "nb_change, "
                 << "visited, "
                 << "time";
    out_file << "\n";

    for(size_t i = 0; i < demands.size(); ++i){
        PathDemand demand = demands[i];
        out_file << data.pt_data->stop_areas[demand.start]->uri
                 << ", " << demand.start
                 << ", " << data.pt_data->stop_areas[demand.target]->uri
                 << ", " << demand.target
                 << ", " << demand.date
                 << ", " << demand.hour;

        out_file << ", "
                 << results[i].arrival << ", "
                 << results[i].duration << ", "
                 << results[i].nb_changes << ", "
                 << results[i].time;

        out_file << "\n";
    }
    out_file.close();

    std::cout << "Number of requests: " << demands.size() << std::endl;
    std::cout << "Number of results with solution: " << nb_reponses << std::endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "base/file_path.h"
#include "base/file_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/ui/ui_layout_test.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_util.h"

static const char* kRootFiles[] = {
  "clear.html",
//  "complex-keys.html",  // Output too big for a cookie.  crbug.com/33472
//  "complex-values.html",  // crbug.com/33472
  "quota.html",
  "remove-item.html",
  "window-attributes-exist.html",
  NULL
};

static const char* kEventsFiles[] = {
//  "basic-body-attribute.html",  // crbug.com/33472
//  "basic.html",  // crbug.com/33472
//  "basic-setattribute.html",  // crbug.com/33472
  "case-sensitive.html",
  "documentURI.html",
  NULL
};

static const char* kStorageFiles[] = {
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "index-get-and-set.html",
  "simple-usage.html",
  "string-conversion.html",
//  "window-open.html", // TODO(jorlow): Fix
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources for most of the DOM Storage layout tests.
  // Add those to the list to be copied.
  void AddJSTestResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    const FilePath dir(FILE_PATH_LITERAL("layout_tests"));
    const FilePath file(FILE_PATH_LITERAL("clear_dom_storage.html"));
    GURL url = ui_test_utils::GetTestUrl(dir, file);
    ASSERT_TRUE(tab->SetCookie(url, ""));
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared",
                            TestTimeouts::action_max_timeout_ms());
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, kNoHttpPort);
      ++files;
    }
  }

  FilePath test_dir_;
};

TEST_F(DOMStorageTest, RootLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  RunTests(kRootFiles);
}

TEST_F(DOMStorageTest, EventLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("events"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("resources"));
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("script-tests"));
  RunTests(kEventsFiles);
}

TEST_F(DOMStorageTest, LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

TEST_F(DOMStorageTest, SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

class DomStorageEmptyDatabaseTest : public UITest {
 protected:
  FilePath StorageDir() const {
    FilePath storage_dir = user_data_dir();
    storage_dir = storage_dir.AppendASCII("Default");
    storage_dir = storage_dir.AppendASCII("Local Storage");
    return storage_dir;
  }

  bool StorageDirIsEmpty() const {
    FilePath storage_dir = StorageDir();
    if (!file_util::DirectoryExists(storage_dir))
      return true;
    return file_util::IsDirectoryEmpty(storage_dir);
  }

  GURL TestUrl() const {
    FilePath test_dir = test_data_directory_;
    FilePath test_file = test_dir.AppendASCII("dom_storage_empty_db.html");
    return net::FilePathToFileURL(test_file);
  }
};

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterClear) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterGet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:get()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

// Flaky, see http://crbug.com/73776
TEST_F(DomStorageEmptyDatabaseTest, FLAKY_NonEmptyDirAfterSet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  QuitBrowser();
  EXPECT_FALSE(StorageDirIsEmpty());

  LaunchBrowserAndServer();
  NavigateToURL(TestUrl());
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}
<commit_msg>Mark flaky test: DOMStorageTest.EventLayoutTests<commit_after>// Copyright (c) 2011 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 "base/file_path.h"
#include "base/file_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/ui/ui_layout_test.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_util.h"

static const char* kRootFiles[] = {
  "clear.html",
//  "complex-keys.html",  // Output too big for a cookie.  crbug.com/33472
//  "complex-values.html",  // crbug.com/33472
  "quota.html",
  "remove-item.html",
  "window-attributes-exist.html",
  NULL
};

static const char* kEventsFiles[] = {
//  "basic-body-attribute.html",  // crbug.com/33472
//  "basic.html",  // crbug.com/33472
//  "basic-setattribute.html",  // crbug.com/33472
  "case-sensitive.html",
  "documentURI.html",
  NULL
};

static const char* kStorageFiles[] = {
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "index-get-and-set.html",
  "simple-usage.html",
  "string-conversion.html",
//  "window-open.html", // TODO(jorlow): Fix
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources for most of the DOM Storage layout tests.
  // Add those to the list to be copied.
  void AddJSTestResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    const FilePath dir(FILE_PATH_LITERAL("layout_tests"));
    const FilePath file(FILE_PATH_LITERAL("clear_dom_storage.html"));
    GURL url = ui_test_utils::GetTestUrl(dir, file);
    ASSERT_TRUE(tab->SetCookie(url, ""));
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared",
                            TestTimeouts::action_max_timeout_ms());
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, kNoHttpPort);
      ++files;
    }
  }

  FilePath test_dir_;
};

TEST_F(DOMStorageTest, RootLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  RunTests(kRootFiles);
}

// Flakily fails on all platforms.  http://crbug.com/102641
TEST_F(DOMStorageTest, FLAKY_EventLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("events"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("resources"));
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("script-tests"));
  RunTests(kEventsFiles);
}

TEST_F(DOMStorageTest, LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

TEST_F(DOMStorageTest, SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

class DomStorageEmptyDatabaseTest : public UITest {
 protected:
  FilePath StorageDir() const {
    FilePath storage_dir = user_data_dir();
    storage_dir = storage_dir.AppendASCII("Default");
    storage_dir = storage_dir.AppendASCII("Local Storage");
    return storage_dir;
  }

  bool StorageDirIsEmpty() const {
    FilePath storage_dir = StorageDir();
    if (!file_util::DirectoryExists(storage_dir))
      return true;
    return file_util::IsDirectoryEmpty(storage_dir);
  }

  GURL TestUrl() const {
    FilePath test_dir = test_data_directory_;
    FilePath test_file = test_dir.AppendASCII("dom_storage_empty_db.html");
    return net::FilePathToFileURL(test_file);
  }
};

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterClear) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterGet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:get()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

// Flaky, see http://crbug.com/73776
TEST_F(DomStorageEmptyDatabaseTest, FLAKY_NonEmptyDirAfterSet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  QuitBrowser();
  EXPECT_FALSE(StorageDirIsEmpty());

  LaunchBrowserAndServer();
  NavigateToURL(TestUrl());
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}
<|endoftext|>


<commit_before>// Copyright 2014 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 "content/common/gpu/client/gl_helper_readback_support.h"
#include "base/logging.h"

namespace content {

GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl)
    : gl_(gl) {
  InitializeReadbackSupport();
}

GLHelperReadbackSupport::~GLHelperReadbackSupport() {}

void GLHelperReadbackSupport::InitializeReadbackSupport() {
  // We are concerned about 16, 32-bit formats only.
  // The below are the most used 16, 32-bit formats.
  // In future if any new format support is needed that should be added here.
  // Initialize the array with FORMAT_NOT_SUPPORTED as we dont know the
  // supported formats yet.
  for (int i = 0; i < SkBitmap::kConfigCount; ++i) {
    format_support_table_[i] = FORMAT_NOT_SUPPORTED;
  }
  CheckForReadbackSupport(SkBitmap::kRGB_565_Config);
  CheckForReadbackSupport(SkBitmap::kARGB_4444_Config);
  CheckForReadbackSupport(SkBitmap::kARGB_8888_Config);
  // Further any formats, support should be checked here.
}

void GLHelperReadbackSupport::CheckForReadbackSupport(
    SkBitmap::Config texture_format) {
  bool supports_format = false;
  switch (texture_format) {
    case SkBitmap::kRGB_565_Config:
      supports_format = SupportsFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
      break;
    case SkBitmap::kARGB_8888_Config:
      supports_format = SupportsFormat(GL_RGBA, GL_UNSIGNED_BYTE);
      break;
    case SkBitmap::kARGB_4444_Config:
      supports_format = false;
      break;
    default:
      NOTREACHED();
      supports_format = false;
      break;
  }
  DCHECK((int)texture_format < (int)SkBitmap::kConfigCount);
  format_support_table_[texture_format] =
      supports_format ? FORMAT_SUPPORTED : FORMAT_NOT_SUPPORTED;
}

bool GLHelperReadbackSupport::SupportsFormat(GLint format, GLint type) {
  const int kTestSize = 64;
  bool supports_format = false;
  content::ScopedTexture dst_texture(gl_);
  ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  gl_->TexImage2D(
      GL_TEXTURE_2D, 0, format, kTestSize, kTestSize, 0, format, type, NULL);
  ScopedFramebuffer dst_framebuffer(gl_);
  ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
                                                             dst_framebuffer);
  gl_->FramebufferTexture2D(
      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_texture, 0);
  GLint ext_format = 0, ext_type = 0;
  gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &ext_format);
  gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &ext_type);
  if ((ext_format == format) && (ext_type == type)) {
    supports_format = true;
  }
  return supports_format;
}

bool GLHelperReadbackSupport::IsReadbackConfigSupported(
    SkBitmap::Config texture_format) {
  switch (format_support_table_[texture_format]) {
    case FORMAT_SUPPORTED:
      return true;
    case FORMAT_NOT_SUPPORTED:
      return false;
    default:
      NOTREACHED();
      return false;
  }
}

}  // namespace content
<commit_msg>Revert 255420 "Revert 255386 "Support ARGB_8888 by default in GL..."<commit_after>// Copyright 2014 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 "content/common/gpu/client/gl_helper_readback_support.h"
#include "base/logging.h"

namespace content {

GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl)
    : gl_(gl) {
  InitializeReadbackSupport();
}

GLHelperReadbackSupport::~GLHelperReadbackSupport() {}

void GLHelperReadbackSupport::InitializeReadbackSupport() {
  // We are concerned about 16, 32-bit formats only.
  // The below are the most used 16, 32-bit formats.
  // In future if any new format support is needed that should be added here.
  // Initialize the array with FORMAT_NOT_SUPPORTED as we dont know the
  // supported formats yet.
  for (int i = 0; i < SkBitmap::kConfigCount; ++i) {
    format_support_table_[i] = FORMAT_NOT_SUPPORTED;
  }
  CheckForReadbackSupport(SkBitmap::kRGB_565_Config);
  CheckForReadbackSupport(SkBitmap::kARGB_4444_Config);
  CheckForReadbackSupport(SkBitmap::kARGB_8888_Config);
  // Further any formats, support should be checked here.
}

void GLHelperReadbackSupport::CheckForReadbackSupport(
    SkBitmap::Config texture_format) {
  bool supports_format = false;
  switch (texture_format) {
    case SkBitmap::kRGB_565_Config:
      supports_format = SupportsFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
      break;
    case SkBitmap::kARGB_8888_Config:
      // This is the baseline, assume always true.
      supports_format = true;
      break;
    case SkBitmap::kARGB_4444_Config:
      supports_format = false;
      break;
    default:
      NOTREACHED();
      supports_format = false;
      break;
  }
  DCHECK((int)texture_format < (int)SkBitmap::kConfigCount);
  format_support_table_[texture_format] =
      supports_format ? FORMAT_SUPPORTED : FORMAT_NOT_SUPPORTED;
}

bool GLHelperReadbackSupport::SupportsFormat(GLint format, GLint type) {
  const int kTestSize = 64;
  bool supports_format = false;
  content::ScopedTexture dst_texture(gl_);
  ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  gl_->TexImage2D(
      GL_TEXTURE_2D, 0, format, kTestSize, kTestSize, 0, format, type, NULL);
  ScopedFramebuffer dst_framebuffer(gl_);
  ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
                                                             dst_framebuffer);
  gl_->FramebufferTexture2D(
      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_texture, 0);
  GLint ext_format = 0, ext_type = 0;
  gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &ext_format);
  gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &ext_type);
  if ((ext_format == format) && (ext_type == type)) {
    supports_format = true;
  }
  return supports_format;
}

bool GLHelperReadbackSupport::IsReadbackConfigSupported(
    SkBitmap::Config texture_format) {
  switch (format_support_table_[texture_format]) {
    case FORMAT_SUPPORTED:
      return true;
    case FORMAT_NOT_SUPPORTED:
      return false;
    default:
      NOTREACHED();
      return false;
  }
}

}  // namespace content
<|endoftext|>


<commit_before>//===-- MachineInstr.cpp --------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Methods common to all machine instructions.
//
// FIXME: Now that MachineInstrs have parent pointers, they should always
// print themselves using their MachineFunction's TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Value.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/MRegisterInfo.h"
#include "Support/LeakDetector.h"
using namespace llvm;

// Global variable holding an array of descriptors for machine instructions.
// The actual object needs to be created separately for each target machine.
// This variable is initialized and reset by class TargetInstrInfo.
//
// FIXME: This should be a property of the target so that more than one target
// at a time can be active...
//
namespace llvm {
  extern const TargetInstrDescriptor *TargetInstrDescriptors;
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(short opcode, unsigned numOperands)
  : Opcode(opcode),
    numImplicitRefs(0),
    operands(numOperands, MachineOperand()),
    parent(0) {
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
}

/// MachineInstr ctor - This constructor only does a _reserve_ of the operands,
/// not a resize for them.  It is expected that if you use this that you call
/// add* methods below to fill up the operands, instead of the Set methods.
/// Eventually, the "resizing" ctors will be phased out.
///
MachineInstr::MachineInstr(short opcode, unsigned numOperands, bool XX, bool YY)
  : Opcode(opcode), numImplicitRefs(0), parent(0) {
  operands.reserve(numOperands);
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
}

/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
/// MachineInstr is created and added to the end of the specified basic block.
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode,
                           unsigned numOperands)
  : Opcode(opcode), numImplicitRefs(0), parent(0) {
  assert(MBB && "Cannot use inserting ctor with null basic block!");
  operands.reserve(numOperands);
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
  MBB->push_back(this);  // Add instruction to end of basic block!
}

MachineInstr::~MachineInstr()
{
  LeakDetector::removeGarbageObject(this);
}

/// OperandComplete - Return true if it's illegal to add a new operand
///
bool MachineInstr::OperandsComplete() const {
  int NumOperands = TargetInstrDescriptors[Opcode].numOperands;
  if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
    return true;  // Broken: we have all the operands of this instruction!
  return false;
}

/// replace - Support for replacing opcode and operands of a MachineInstr in
/// place. This only resets the size of the operand vector and initializes it.
/// The new operands must be set explicitly later.
///
void MachineInstr::replace(short opcode, unsigned numOperands) {
  assert(getNumImplicitRefs() == 0 &&
         "This is probably broken because implicit refs are going to be lost.");
  Opcode = opcode;
  operands.clear();
  operands.resize(numOperands, MachineOperand());
}

void MachineInstr::SetMachineOperandVal(unsigned i,
                                        MachineOperand::MachineOperandType opTy,
                                        Value* V) {
  assert(i < operands.size());          // may be explicit or implicit op
  operands[i].opType = opTy;
  operands[i].value = V;
  operands[i].regNum = -1;
}

void
MachineInstr::SetMachineOperandConst(unsigned i,
                                     MachineOperand::MachineOperandType opTy,
                                     int64_t intValue) {
  assert(i < getNumOperands());          // must be explicit op
  assert(TargetInstrDescriptors[Opcode].resultPos != (int) i &&
         "immed. constant cannot be defined");

  operands[i].opType = opTy;
  operands[i].value = NULL;
  operands[i].immedVal = intValue;
  operands[i].regNum = -1;
  operands[i].flags = 0;
}

void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
  assert(i < getNumOperands());          // must be explicit op

  operands[i].opType = MachineOperand::MO_MachineRegister;
  operands[i].value = NULL;
  operands[i].regNum = regNum;
}

// Used only by the SPARC back-end.
void MachineInstr::SetRegForOperand(unsigned i, int regNum) {
  assert(i < getNumOperands());          // must be explicit op
  operands[i].setRegForValue(regNum);
}

// Used only by the SPARC back-end.
void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) {
  getImplicitOp(i).setRegForValue(regNum);
}

/// substituteValue - Substitute all occurrences of Value* oldVal with newVal
/// in all operands and all implicit refs. If defsOnly == true, substitute defs
/// only.
///
/// FIXME: Fold this into its single caller, at SparcInstrSelection.cpp:2865,
/// or make it a static function in that file.
///
unsigned
MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
                              bool defsOnly, bool notDefsAndUses,
                              bool& someArgsWereIgnored)
{
  assert((!defsOnly || !notDefsAndUses) &&
         "notDefsAndUses is irrelevant if defsOnly == true.");

  unsigned numSubst = 0;

  // Substitute operands
  for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
    if (*O == oldVal)
      if (!defsOnly ||
          notDefsAndUses && (O.isDef() && !O.isUse()) ||
          !notDefsAndUses && O.isDef())
        {
          O.getMachineOperand().value = newVal;
          ++numSubst;
        }
      else
        someArgsWereIgnored = true;

  // Substitute implicit refs
  for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
    if (getImplicitRef(i) == oldVal)
      if (!defsOnly ||
          notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) ||
          !notDefsAndUses && getImplicitOp(i).isDef())
        {
          getImplicitOp(i).value = newVal;
          ++numSubst;
        }
      else
        someArgsWereIgnored = true;

  return numSubst;
}

void MachineInstr::dump() const {
  std::cerr << "  " << *this;
}

static inline std::ostream& OutputValue(std::ostream &os, const Value* val) {
  os << "(val ";
  os << (void*) val;                    // print address always
  if (val && val->hasName())
    os << " " << val->getName(); // print name also, if available
  os << ")";
  return os;
}

static inline void OutputReg(std::ostream &os, unsigned RegNo,
                             const MRegisterInfo *MRI = 0) {
  if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) {
    if (MRI)
      os << "%" << MRI->get(RegNo).Name;
    else
      os << "%mreg(" << RegNo << ")";
  } else
    os << "%reg" << RegNo;
}

static void print(const MachineOperand &MO, std::ostream &OS,
                  const TargetMachine &TM) {
  const MRegisterInfo *MRI = TM.getRegisterInfo();
  bool CloseParen = true;
  if (MO.isHiBits32())
    OS << "%lm(";
  else if (MO.isLoBits32())
    OS << "%lo(";
  else if (MO.isHiBits64())
    OS << "%hh(";
  else if (MO.isLoBits64())
    OS << "%hm(";
  else
    CloseParen = false;

  switch (MO.getType()) {
  case MachineOperand::MO_VirtualRegister:
    if (MO.getVRegValue()) {
      OS << "%reg";
      OutputValue(OS, MO.getVRegValue());
      if (MO.hasAllocatedReg())
        OS << "==";
    }
    if (MO.hasAllocatedReg())
      OutputReg(OS, MO.getReg(), MRI);
    break;
  case MachineOperand::MO_CCRegister:
    OS << "%ccreg";
    OutputValue(OS, MO.getVRegValue());
    if (MO.hasAllocatedReg()) {
      OS << "==";
      OutputReg(OS, MO.getReg(), MRI);
    }
    break;
  case MachineOperand::MO_MachineRegister:
    OutputReg(OS, MO.getMachineRegNum(), MRI);
    break;
  case MachineOperand::MO_SignExtendedImmed:
    OS << (long)MO.getImmedValue();
    break;
  case MachineOperand::MO_UnextendedImmed:
    OS << (long)MO.getImmedValue();
    break;
  case MachineOperand::MO_PCRelativeDisp: {
    const Value* opVal = MO.getVRegValue();
    bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
    OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
    if (opVal->hasName())
      OS << opVal->getName();
    else
      OS << (const void*) opVal;
    OS << ")";
    break;
  }
  case MachineOperand::MO_MachineBasicBlock:
    OS << "bb<"
       << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
       << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
    break;
  case MachineOperand::MO_FrameIndex:
    OS << "<fi#" << MO.getFrameIndex() << ">";
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    OS << "<cp#" << MO.getConstantPoolIndex() << ">";
    break;
  case MachineOperand::MO_GlobalAddress:
    OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
    break;
  case MachineOperand::MO_ExternalSymbol:
    OS << "<es:" << MO.getSymbolName() << ">";
    break;
  default:
    assert(0 && "Unrecognized operand type");
  }

  if (CloseParen)
    OS << ")";
}

void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const {
  unsigned StartOp = 0;

   // Specialize printing if op#0 is definition
  if (getNumOperands() && getOperand(0).isDef() && !getOperand(0).isUse()) {
    ::print(getOperand(0), OS, TM);
    OS << " = ";
    ++StartOp;   // Don't print this operand again!
  }
  OS << TM.getInstrInfo().getName(getOpcode());

  for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
    const MachineOperand& mop = getOperand(i);
    if (i != StartOp)
      OS << ",";
    OS << " ";
    ::print(mop, OS, TM);

    if (mop.isDef())
      if (mop.isUse())
        OS << "<def&use>";
      else
        OS << "<def>";
  }

  // code for printing implicit references
  if (getNumImplicitRefs()) {
    OS << "\tImplicitRefs: ";
    for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
      OS << "\t";
      OutputValue(OS, getImplicitRef(i));
      if (getImplicitOp(i).isDef())
          if (getImplicitOp(i).isUse())
            OS << "<def&use>";
          else
            OS << "<def>";
    }
  }

  OS << "\n";
}

namespace llvm {
std::ostream &operator<<(std::ostream &os, const MachineInstr &MI) {
  // If the instruction is embedded into a basic block, we can find the target
  // info for the instruction.
  if (const MachineBasicBlock *MBB = MI.getParent()) {
    const MachineFunction *MF = MBB->getParent();
    MI.print(os, MF->getTarget());
    return os;
  }

  // Otherwise, print it out in the "raw" format without symbolic register names
  // and such.
  os << TargetInstrDescriptors[MI.getOpcode()].Name;

  for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
    os << "\t" << MI.getOperand(i);
    if (MI.getOperand(i).isDef())
      if (MI.getOperand(i).isUse())
        os << "<d&u>";
      else
        os << "<d>";
  }

  // code for printing implicit references
  unsigned NumOfImpRefs = MI.getNumImplicitRefs();
  if (NumOfImpRefs > 0) {
    os << "\tImplicit: ";
    for (unsigned z=0; z < NumOfImpRefs; z++) {
      OutputValue(os, MI.getImplicitRef(z));
      if (MI.getImplicitOp(z).isDef())
          if (MI.getImplicitOp(z).isUse())
            os << "<d&u>";
          else
            os << "<d>";
      os << "\t";
    }
  }

  return os << "\n";
}

std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
  if (MO.isHiBits32())
    OS << "%lm(";
  else if (MO.isLoBits32())
    OS << "%lo(";
  else if (MO.isHiBits64())
    OS << "%hh(";
  else if (MO.isLoBits64())
    OS << "%hm(";

  switch (MO.getType())
    {
    case MachineOperand::MO_VirtualRegister:
      if (MO.hasAllocatedReg())
        OutputReg(OS, MO.getReg());

      if (MO.getVRegValue()) {
	if (MO.hasAllocatedReg()) OS << "==";
	OS << "%vreg";
	OutputValue(OS, MO.getVRegValue());
      }
      break;
    case MachineOperand::MO_CCRegister:
      OS << "%ccreg";
      OutputValue(OS, MO.getVRegValue());
      if (MO.hasAllocatedReg()) {
        OS << "==";
        OutputReg(OS, MO.getReg());
      }
      break;
    case MachineOperand::MO_MachineRegister:
      OutputReg(OS, MO.getMachineRegNum());
      break;
    case MachineOperand::MO_SignExtendedImmed:
      OS << (long)MO.getImmedValue();
      break;
    case MachineOperand::MO_UnextendedImmed:
      OS << (long)MO.getImmedValue();
      break;
    case MachineOperand::MO_PCRelativeDisp:
      {
        const Value* opVal = MO.getVRegValue();
        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
        OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
        if (opVal->hasName())
          OS << opVal->getName();
        else
          OS << (const void*) opVal;
        OS << ")";
        break;
      }
    case MachineOperand::MO_MachineBasicBlock:
      OS << "bb<"
         << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
         << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
      break;
    case MachineOperand::MO_FrameIndex:
      OS << "<fi#" << MO.getFrameIndex() << ">";
      break;
    case MachineOperand::MO_ConstantPoolIndex:
      OS << "<cp#" << MO.getConstantPoolIndex() << ">";
      break;
    case MachineOperand::MO_GlobalAddress:
      OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
      break;
    case MachineOperand::MO_ExternalSymbol:
      OS << "<es:" << MO.getSymbolName() << ">";
      break;
    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  if (MO.isHiBits32() || MO.isLoBits32() || MO.isHiBits64() || MO.isLoBits64())
    OS << ")";

  return OS;
}

}
<commit_msg>int64_t -> int<commit_after>//===-- MachineInstr.cpp --------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Methods common to all machine instructions.
//
// FIXME: Now that MachineInstrs have parent pointers, they should always
// print themselves using their MachineFunction's TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Value.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/MRegisterInfo.h"
#include "Support/LeakDetector.h"
using namespace llvm;

// Global variable holding an array of descriptors for machine instructions.
// The actual object needs to be created separately for each target machine.
// This variable is initialized and reset by class TargetInstrInfo.
//
// FIXME: This should be a property of the target so that more than one target
// at a time can be active...
//
namespace llvm {
  extern const TargetInstrDescriptor *TargetInstrDescriptors;
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(short opcode, unsigned numOperands)
  : Opcode(opcode),
    numImplicitRefs(0),
    operands(numOperands, MachineOperand()),
    parent(0) {
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
}

/// MachineInstr ctor - This constructor only does a _reserve_ of the operands,
/// not a resize for them.  It is expected that if you use this that you call
/// add* methods below to fill up the operands, instead of the Set methods.
/// Eventually, the "resizing" ctors will be phased out.
///
MachineInstr::MachineInstr(short opcode, unsigned numOperands, bool XX, bool YY)
  : Opcode(opcode), numImplicitRefs(0), parent(0) {
  operands.reserve(numOperands);
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
}

/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
/// MachineInstr is created and added to the end of the specified basic block.
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode,
                           unsigned numOperands)
  : Opcode(opcode), numImplicitRefs(0), parent(0) {
  assert(MBB && "Cannot use inserting ctor with null basic block!");
  operands.reserve(numOperands);
  // Make sure that we get added to a machine basicblock
  LeakDetector::addGarbageObject(this);
  MBB->push_back(this);  // Add instruction to end of basic block!
}

MachineInstr::~MachineInstr()
{
  LeakDetector::removeGarbageObject(this);
}

/// OperandComplete - Return true if it's illegal to add a new operand
///
bool MachineInstr::OperandsComplete() const {
  int NumOperands = TargetInstrDescriptors[Opcode].numOperands;
  if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
    return true;  // Broken: we have all the operands of this instruction!
  return false;
}

/// replace - Support for replacing opcode and operands of a MachineInstr in
/// place. This only resets the size of the operand vector and initializes it.
/// The new operands must be set explicitly later.
///
void MachineInstr::replace(short opcode, unsigned numOperands) {
  assert(getNumImplicitRefs() == 0 &&
         "This is probably broken because implicit refs are going to be lost.");
  Opcode = opcode;
  operands.clear();
  operands.resize(numOperands, MachineOperand());
}

void MachineInstr::SetMachineOperandVal(unsigned i,
                                        MachineOperand::MachineOperandType opTy,
                                        Value* V) {
  assert(i < operands.size());          // may be explicit or implicit op
  operands[i].opType = opTy;
  operands[i].value = V;
  operands[i].regNum = -1;
}

void
MachineInstr::SetMachineOperandConst(unsigned i,
                                     MachineOperand::MachineOperandType opTy,
                                     int intValue) {
  assert(i < getNumOperands());          // must be explicit op
  assert(TargetInstrDescriptors[Opcode].resultPos != (int) i &&
         "immed. constant cannot be defined");

  operands[i].opType = opTy;
  operands[i].value = NULL;
  operands[i].immedVal = intValue;
  operands[i].regNum = -1;
  operands[i].flags = 0;
}

void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
  assert(i < getNumOperands());          // must be explicit op

  operands[i].opType = MachineOperand::MO_MachineRegister;
  operands[i].value = NULL;
  operands[i].regNum = regNum;
}

// Used only by the SPARC back-end.
void MachineInstr::SetRegForOperand(unsigned i, int regNum) {
  assert(i < getNumOperands());          // must be explicit op
  operands[i].setRegForValue(regNum);
}

// Used only by the SPARC back-end.
void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) {
  getImplicitOp(i).setRegForValue(regNum);
}

/// substituteValue - Substitute all occurrences of Value* oldVal with newVal
/// in all operands and all implicit refs. If defsOnly == true, substitute defs
/// only.
///
/// FIXME: Fold this into its single caller, at SparcInstrSelection.cpp:2865,
/// or make it a static function in that file.
///
unsigned
MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
                              bool defsOnly, bool notDefsAndUses,
                              bool& someArgsWereIgnored)
{
  assert((!defsOnly || !notDefsAndUses) &&
         "notDefsAndUses is irrelevant if defsOnly == true.");

  unsigned numSubst = 0;

  // Substitute operands
  for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
    if (*O == oldVal)
      if (!defsOnly ||
          notDefsAndUses && (O.isDef() && !O.isUse()) ||
          !notDefsAndUses && O.isDef())
        {
          O.getMachineOperand().value = newVal;
          ++numSubst;
        }
      else
        someArgsWereIgnored = true;

  // Substitute implicit refs
  for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
    if (getImplicitRef(i) == oldVal)
      if (!defsOnly ||
          notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) ||
          !notDefsAndUses && getImplicitOp(i).isDef())
        {
          getImplicitOp(i).value = newVal;
          ++numSubst;
        }
      else
        someArgsWereIgnored = true;

  return numSubst;
}

void MachineInstr::dump() const {
  std::cerr << "  " << *this;
}

static inline std::ostream& OutputValue(std::ostream &os, const Value* val) {
  os << "(val ";
  os << (void*) val;                    // print address always
  if (val && val->hasName())
    os << " " << val->getName(); // print name also, if available
  os << ")";
  return os;
}

static inline void OutputReg(std::ostream &os, unsigned RegNo,
                             const MRegisterInfo *MRI = 0) {
  if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) {
    if (MRI)
      os << "%" << MRI->get(RegNo).Name;
    else
      os << "%mreg(" << RegNo << ")";
  } else
    os << "%reg" << RegNo;
}

static void print(const MachineOperand &MO, std::ostream &OS,
                  const TargetMachine &TM) {
  const MRegisterInfo *MRI = TM.getRegisterInfo();
  bool CloseParen = true;
  if (MO.isHiBits32())
    OS << "%lm(";
  else if (MO.isLoBits32())
    OS << "%lo(";
  else if (MO.isHiBits64())
    OS << "%hh(";
  else if (MO.isLoBits64())
    OS << "%hm(";
  else
    CloseParen = false;

  switch (MO.getType()) {
  case MachineOperand::MO_VirtualRegister:
    if (MO.getVRegValue()) {
      OS << "%reg";
      OutputValue(OS, MO.getVRegValue());
      if (MO.hasAllocatedReg())
        OS << "==";
    }
    if (MO.hasAllocatedReg())
      OutputReg(OS, MO.getReg(), MRI);
    break;
  case MachineOperand::MO_CCRegister:
    OS << "%ccreg";
    OutputValue(OS, MO.getVRegValue());
    if (MO.hasAllocatedReg()) {
      OS << "==";
      OutputReg(OS, MO.getReg(), MRI);
    }
    break;
  case MachineOperand::MO_MachineRegister:
    OutputReg(OS, MO.getMachineRegNum(), MRI);
    break;
  case MachineOperand::MO_SignExtendedImmed:
    OS << (long)MO.getImmedValue();
    break;
  case MachineOperand::MO_UnextendedImmed:
    OS << (long)MO.getImmedValue();
    break;
  case MachineOperand::MO_PCRelativeDisp: {
    const Value* opVal = MO.getVRegValue();
    bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
    OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
    if (opVal->hasName())
      OS << opVal->getName();
    else
      OS << (const void*) opVal;
    OS << ")";
    break;
  }
  case MachineOperand::MO_MachineBasicBlock:
    OS << "bb<"
       << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
       << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
    break;
  case MachineOperand::MO_FrameIndex:
    OS << "<fi#" << MO.getFrameIndex() << ">";
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    OS << "<cp#" << MO.getConstantPoolIndex() << ">";
    break;
  case MachineOperand::MO_GlobalAddress:
    OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
    break;
  case MachineOperand::MO_ExternalSymbol:
    OS << "<es:" << MO.getSymbolName() << ">";
    break;
  default:
    assert(0 && "Unrecognized operand type");
  }

  if (CloseParen)
    OS << ")";
}

void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const {
  unsigned StartOp = 0;

   // Specialize printing if op#0 is definition
  if (getNumOperands() && getOperand(0).isDef() && !getOperand(0).isUse()) {
    ::print(getOperand(0), OS, TM);
    OS << " = ";
    ++StartOp;   // Don't print this operand again!
  }
  OS << TM.getInstrInfo().getName(getOpcode());

  for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
    const MachineOperand& mop = getOperand(i);
    if (i != StartOp)
      OS << ",";
    OS << " ";
    ::print(mop, OS, TM);

    if (mop.isDef())
      if (mop.isUse())
        OS << "<def&use>";
      else
        OS << "<def>";
  }

  // code for printing implicit references
  if (getNumImplicitRefs()) {
    OS << "\tImplicitRefs: ";
    for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
      OS << "\t";
      OutputValue(OS, getImplicitRef(i));
      if (getImplicitOp(i).isDef())
          if (getImplicitOp(i).isUse())
            OS << "<def&use>";
          else
            OS << "<def>";
    }
  }

  OS << "\n";
}

namespace llvm {
std::ostream &operator<<(std::ostream &os, const MachineInstr &MI) {
  // If the instruction is embedded into a basic block, we can find the target
  // info for the instruction.
  if (const MachineBasicBlock *MBB = MI.getParent()) {
    const MachineFunction *MF = MBB->getParent();
    MI.print(os, MF->getTarget());
    return os;
  }

  // Otherwise, print it out in the "raw" format without symbolic register names
  // and such.
  os << TargetInstrDescriptors[MI.getOpcode()].Name;

  for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
    os << "\t" << MI.getOperand(i);
    if (MI.getOperand(i).isDef())
      if (MI.getOperand(i).isUse())
        os << "<d&u>";
      else
        os << "<d>";
  }

  // code for printing implicit references
  unsigned NumOfImpRefs = MI.getNumImplicitRefs();
  if (NumOfImpRefs > 0) {
    os << "\tImplicit: ";
    for (unsigned z=0; z < NumOfImpRefs; z++) {
      OutputValue(os, MI.getImplicitRef(z));
      if (MI.getImplicitOp(z).isDef())
          if (MI.getImplicitOp(z).isUse())
            os << "<d&u>";
          else
            os << "<d>";
      os << "\t";
    }
  }

  return os << "\n";
}

std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
  if (MO.isHiBits32())
    OS << "%lm(";
  else if (MO.isLoBits32())
    OS << "%lo(";
  else if (MO.isHiBits64())
    OS << "%hh(";
  else if (MO.isLoBits64())
    OS << "%hm(";

  switch (MO.getType())
    {
    case MachineOperand::MO_VirtualRegister:
      if (MO.hasAllocatedReg())
        OutputReg(OS, MO.getReg());

      if (MO.getVRegValue()) {
	if (MO.hasAllocatedReg()) OS << "==";
	OS << "%vreg";
	OutputValue(OS, MO.getVRegValue());
      }
      break;
    case MachineOperand::MO_CCRegister:
      OS << "%ccreg";
      OutputValue(OS, MO.getVRegValue());
      if (MO.hasAllocatedReg()) {
        OS << "==";
        OutputReg(OS, MO.getReg());
      }
      break;
    case MachineOperand::MO_MachineRegister:
      OutputReg(OS, MO.getMachineRegNum());
      break;
    case MachineOperand::MO_SignExtendedImmed:
      OS << (long)MO.getImmedValue();
      break;
    case MachineOperand::MO_UnextendedImmed:
      OS << (long)MO.getImmedValue();
      break;
    case MachineOperand::MO_PCRelativeDisp:
      {
        const Value* opVal = MO.getVRegValue();
        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
        OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
        if (opVal->hasName())
          OS << opVal->getName();
        else
          OS << (const void*) opVal;
        OS << ")";
        break;
      }
    case MachineOperand::MO_MachineBasicBlock:
      OS << "bb<"
         << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
         << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
      break;
    case MachineOperand::MO_FrameIndex:
      OS << "<fi#" << MO.getFrameIndex() << ">";
      break;
    case MachineOperand::MO_ConstantPoolIndex:
      OS << "<cp#" << MO.getConstantPoolIndex() << ">";
      break;
    case MachineOperand::MO_GlobalAddress:
      OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
      break;
    case MachineOperand::MO_ExternalSymbol:
      OS << "<es:" << MO.getSymbolName() << ">";
      break;
    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  if (MO.isHiBits32() || MO.isLoBits32() || MO.isHiBits64() || MO.isLoBits64())
    OS << ")";

  return OS;
}

}
<|endoftext|>


<commit_before>// Copyright 2020 Chia Network Inc

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in coiance 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 iied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_BLSSCHEMES_HPP_
#define SRC_BLSSCHEMES_HPP_

#include <iostream>
#include <vector>

#include <relic_conf.h>

#if defined GMP && ARITH == GMP
#include <gmp.h>
#endif

#include "elements.hpp"
#include "privatekey.hpp"

using std::vector;

// These are all MPL schemes
namespace bls {

class Bytes;

class CoreMPL {

public:
    CoreMPL() = delete;
    CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {}
    // Generates a private key from a seed, similar to HD key generation
    // (hashes the seed), and reduces it mod the group order
    virtual PrivateKey KeyGen(const vector<uint8_t>& seed);
    virtual PrivateKey KeyGen(const Bytes& seed);

    // Generates a public key from a secret key
    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey);

    virtual G1Element SkToG1(const PrivateKey &seckey);

    virtual G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message);
    virtual G2Element Sign(const PrivateKey& seckey, const Bytes& message);

    virtual bool Verify(const vector<uint8_t> &pubkey,
                        const vector<uint8_t> &message,
                        const vector<uint8_t> &signature);

    virtual bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature);

    virtual bool Verify(const G1Element &pubkey,
                        const vector<uint8_t> &message,
                        const G2Element &signature);

    virtual bool Verify(const G1Element& pubkey, const Bytes& message, const G2Element& signature);

    virtual vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures);
    virtual vector<uint8_t> Aggregate(const vector<Bytes>& signatures);

    virtual G2Element Aggregate(const vector<G2Element> &signatures);

    virtual G1Element Aggregate(const vector<G1Element> &publicKeys);

    virtual G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                                      const std::vector<G2Element>& vecSignatures,
                                      const Bytes& message);

    virtual bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                              const G2Element& signature,
                              const Bytes& message);

    virtual bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const vector<uint8_t> &signature);

    virtual bool AggregateVerify(const vector<Bytes>& pubkeys,
                                 const vector<Bytes>& messages,
                                 const Bytes& signature);

    virtual bool AggregateVerify(const vector<G1Element> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const G2Element &signature);

     virtual bool AggregateVerify(const vector<G1Element>& pubkeys,
                                  const vector<Bytes>& messages,
                                  const G2Element& signature);

    PrivateKey DeriveChildSk(const PrivateKey& sk, uint32_t index);
    PrivateKey DeriveChildSkUnhardened(const PrivateKey& sk, uint32_t index);
    G1Element DeriveChildPkUnhardened(const G1Element& sk, uint32_t index);

protected:
    const std::string& strCiphersuiteId;
    bool NativeVerify(g1_t *pubKeys, g2_t *mappedHashes, size_t length);
    G2Element AggregateSecure(std::vector<G1Element> const &vecPublicKeys,
                              std::vector<G2Element> const &vecSignatures,
                              const Bytes& message,
                              bool fLegacy);
    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message,
                      bool fLegacy);
};

class BasicSchemeMPL : public CoreMPL {
public:
    static const std::string CIPHERSUITE_ID;
    BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {}
    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class AugSchemeMPL : public CoreMPL {

public:
    static const std::string CIPHERSUITE_ID;
    AugSchemeMPL() : CoreMPL(AugSchemeMPL::CIPHERSUITE_ID) {}

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) override;

    G2Element Sign(const PrivateKey& seckey, const Bytes& message) override;

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey &seckey,
                   const vector<uint8_t> &message,
                   const G1Element &prepend_pk);

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey& seckey,
                   const Bytes& message,
                   const G1Element& prepend_pk);

    bool Verify(const vector<uint8_t> &pubkey,
                const vector<uint8_t> &message,
                const vector<uint8_t> &signature) override;

    bool Verify(const Bytes& pubkey,
                const Bytes& message,
                const Bytes& signature) override;

    bool Verify(const G1Element &pubkey,
                const vector<uint8_t> &message,
                const G2Element &signature) override;

    bool Verify(const G1Element& pubkey,
                const Bytes& message,
                const G2Element& signature) override;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class PopSchemeMPL : public CoreMPL {

public:
    static const std::string CIPHERSUITE_ID;
    static const std::string POP_CIPHERSUITE_ID;
    PopSchemeMPL() : CoreMPL(PopSchemeMPL::CIPHERSUITE_ID) {}

    G2Element PopProve(const PrivateKey &seckey);

    bool PopVerify(const G1Element &pubkey, const G2Element &signature_proof);

    bool PopVerify(const vector<uint8_t> &pubkey, const vector<uint8_t> &proof);

    bool PopVerify(const Bytes& pubkey, const Bytes& proof);

    bool FastAggregateVerify(const vector<G1Element> &pubkeys,
                             const vector<uint8_t> &message,
                             const G2Element &signature);

    bool FastAggregateVerify(const vector<G1Element>& pubkeys,
                             const Bytes& message,
                             const G2Element& signature);

    bool FastAggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                             const vector<uint8_t> &message,
                             const vector<uint8_t> &signature);

    bool FastAggregateVerify(const vector<Bytes>& pubkeys,
                             const Bytes& message,
                             const Bytes& signature);
};

/**
 * This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29).
 */
class LegacySchemeMPL : public CoreMPL {

public:
    LegacySchemeMPL() : CoreMPL(std::string{}) {}

    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    G2Element Sign(const PrivateKey &seckey, const Bytes& message) final;

    bool Verify(const vector<uint8_t>& pubkey,
                const vector<uint8_t>& message,
                const vector<uint8_t>& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const G1Element& pubkey,
                const vector<uint8_t>& message,
                const G2Element& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    bool Verify(const G1Element &pubkey, const Bytes& message, const G2Element &signature) final;

    vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                              const std::vector<G2Element>& vecSignatures,
                              const Bytes& message) final;

    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message) final;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<Bytes> &pubkeys,
                         const vector<Bytes> &messages,
                         const Bytes &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<Bytes> &messages,
                         const G2Element &signature) final;
};
}  // end namespace bls

#endif  // SRC_BLSSCHEMES_HPP_
<commit_msg>add virtual dtor's for scheme's in new BLS impl<commit_after>// Copyright 2020 Chia Network Inc

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in coiance 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 iied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_BLSSCHEMES_HPP_
#define SRC_BLSSCHEMES_HPP_

#include <iostream>
#include <vector>

#include <relic_conf.h>

#if defined GMP && ARITH == GMP
#include <gmp.h>
#endif

#include "elements.hpp"
#include "privatekey.hpp"

using std::vector;

// These are all MPL schemes
namespace bls {

class Bytes;

class CoreMPL {

public:
    virtual ~CoreMPL() {};
    CoreMPL() = delete;
    CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {}
    // Generates a private key from a seed, similar to HD key generation
    // (hashes the seed), and reduces it mod the group order
    virtual PrivateKey KeyGen(const vector<uint8_t>& seed);
    virtual PrivateKey KeyGen(const Bytes& seed);

    // Generates a public key from a secret key
    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey);

    virtual G1Element SkToG1(const PrivateKey &seckey);

    virtual G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message);
    virtual G2Element Sign(const PrivateKey& seckey, const Bytes& message);

    virtual bool Verify(const vector<uint8_t> &pubkey,
                        const vector<uint8_t> &message,
                        const vector<uint8_t> &signature);

    virtual bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature);

    virtual bool Verify(const G1Element &pubkey,
                        const vector<uint8_t> &message,
                        const G2Element &signature);

    virtual bool Verify(const G1Element& pubkey, const Bytes& message, const G2Element& signature);

    virtual vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures);
    virtual vector<uint8_t> Aggregate(const vector<Bytes>& signatures);

    virtual G2Element Aggregate(const vector<G2Element> &signatures);

    virtual G1Element Aggregate(const vector<G1Element> &publicKeys);

    virtual G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                                      const std::vector<G2Element>& vecSignatures,
                                      const Bytes& message);

    virtual bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                              const G2Element& signature,
                              const Bytes& message);

    virtual bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const vector<uint8_t> &signature);

    virtual bool AggregateVerify(const vector<Bytes>& pubkeys,
                                 const vector<Bytes>& messages,
                                 const Bytes& signature);

    virtual bool AggregateVerify(const vector<G1Element> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const G2Element &signature);

     virtual bool AggregateVerify(const vector<G1Element>& pubkeys,
                                  const vector<Bytes>& messages,
                                  const G2Element& signature);

    PrivateKey DeriveChildSk(const PrivateKey& sk, uint32_t index);
    PrivateKey DeriveChildSkUnhardened(const PrivateKey& sk, uint32_t index);
    G1Element DeriveChildPkUnhardened(const G1Element& sk, uint32_t index);

protected:
    const std::string& strCiphersuiteId;
    bool NativeVerify(g1_t *pubKeys, g2_t *mappedHashes, size_t length);
    G2Element AggregateSecure(std::vector<G1Element> const &vecPublicKeys,
                              std::vector<G2Element> const &vecSignatures,
                              const Bytes& message,
                              bool fLegacy);
    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message,
                      bool fLegacy);
};

class BasicSchemeMPL : public CoreMPL {
public:
    virtual ~BasicSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {}
    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class AugSchemeMPL : public CoreMPL {

public:
    virtual ~AugSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    AugSchemeMPL() : CoreMPL(AugSchemeMPL::CIPHERSUITE_ID) {}

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) override;

    G2Element Sign(const PrivateKey& seckey, const Bytes& message) override;

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey &seckey,
                   const vector<uint8_t> &message,
                   const G1Element &prepend_pk);

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey& seckey,
                   const Bytes& message,
                   const G1Element& prepend_pk);

    bool Verify(const vector<uint8_t> &pubkey,
                const vector<uint8_t> &message,
                const vector<uint8_t> &signature) override;

    bool Verify(const Bytes& pubkey,
                const Bytes& message,
                const Bytes& signature) override;

    bool Verify(const G1Element &pubkey,
                const vector<uint8_t> &message,
                const G2Element &signature) override;

    bool Verify(const G1Element& pubkey,
                const Bytes& message,
                const G2Element& signature) override;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class PopSchemeMPL : public CoreMPL {

public:
    virtual ~PopSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    static const std::string POP_CIPHERSUITE_ID;
    PopSchemeMPL() : CoreMPL(PopSchemeMPL::CIPHERSUITE_ID) {}

    G2Element PopProve(const PrivateKey &seckey);

    bool PopVerify(const G1Element &pubkey, const G2Element &signature_proof);

    bool PopVerify(const vector<uint8_t> &pubkey, const vector<uint8_t> &proof);

    bool PopVerify(const Bytes& pubkey, const Bytes& proof);

    bool FastAggregateVerify(const vector<G1Element> &pubkeys,
                             const vector<uint8_t> &message,
                             const G2Element &signature);

    bool FastAggregateVerify(const vector<G1Element>& pubkeys,
                             const Bytes& message,
                             const G2Element& signature);

    bool FastAggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                             const vector<uint8_t> &message,
                             const vector<uint8_t> &signature);

    bool FastAggregateVerify(const vector<Bytes>& pubkeys,
                             const Bytes& message,
                             const Bytes& signature);
};

/**
 * This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29).
 */
class LegacySchemeMPL : public CoreMPL {

public:
    virtual ~LegacySchemeMPL() {};
    LegacySchemeMPL() : CoreMPL(std::string{}) {}

    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    G2Element Sign(const PrivateKey &seckey, const Bytes& message) final;

    bool Verify(const vector<uint8_t>& pubkey,
                const vector<uint8_t>& message,
                const vector<uint8_t>& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const G1Element& pubkey,
                const vector<uint8_t>& message,
                const G2Element& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    bool Verify(const G1Element &pubkey, const Bytes& message, const G2Element &signature) final;

    vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                              const std::vector<G2Element>& vecSignatures,
                              const Bytes& message) final;

    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message) final;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<Bytes> &pubkeys,
                         const vector<Bytes> &messages,
                         const Bytes &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<Bytes> &messages,
                         const G2Element &signature) final;
};
}  // end namespace bls

#endif  // SRC_BLSSCHEMES_HPP_
<|endoftext|>