<commit_before>#include <iostream>
#include <fstream>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <map>
#include <list>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>

#include "tree.hh"
#include "tree-image.hh"
#include "xz.hh"

// ----------------------------------------------------------------------

std::pair<double, size_t> Node::width_height() const
{
    size_t height = 0;
    double width = 0;
    if (is_leaf()) {
        ++height;
    }
    else {
        for (auto node = subtree.begin(); node != subtree.end(); ++node) {
            auto const wh = node->width_height();
            if (wh.first > width)
                width = wh.first;
            height += wh.second;
        }
    }
    return std::make_pair(width + edge_length, height);

} // Node::width_height

// ----------------------------------------------------------------------

int Node::months_from(const Date& aStart) const
{
    return date.empty() ? -1 : months_between_dates(aStart, date);

} // Node::month_no

// ----------------------------------------------------------------------

void Tree::analyse()
{
      // set line_no for each name node
    size_t current_line = 0;
    auto set_line_no = [&current_line](Node& aNode) {
        aNode.line_no = current_line;
        ++current_line;
    };
      // set top and bottom for each subtree node
    auto set_top_bottom = [](Node& aNode) {
        aNode.top = aNode.subtree.begin()->middle();
        aNode.bottom = aNode.subtree.rbegin()->middle();
    };
    iterate<Node&>(*this, set_line_no, &nope, set_top_bottom);

} // Tree::analyse

// ----------------------------------------------------------------------

std::pair<Date, Date> Tree::min_max_date() const
{
    Date min_date, max_date;
    auto min_max_date = [&min_date, &max_date](const Node& aNode) -> void {
        if (!aNode.date.empty()) {
            if (min_date.empty() || aNode.date < min_date)
                min_date = aNode.date;
            if (max_date.empty() || max_date < aNode.date)
                max_date = aNode.date;
        }
    };
    iterate<const Node&>(*this, min_max_date);
    return std::make_pair(min_date, max_date);

} // Tree::min_max_date

// ----------------------------------------------------------------------

std::pair<double, double> Tree::min_max_edge() const
{
    double min_edge = 1e99, max_edge = 0.0;
    auto min_max_edge = [&min_edge, &max_edge](const Node& aNode) -> void {
        if (aNode.edge_length > 0.0) {
            if (aNode.edge_length < min_edge)
                min_edge = aNode.edge_length;
            if (max_edge < aNode.edge_length)
                max_edge = aNode.edge_length;
        }
    };
    iterate<const Node&>(*this, min_max_edge, min_max_edge);
    return std::make_pair(min_edge, max_edge);

} // Tree::min_max_edge

// ----------------------------------------------------------------------

std::pair<const Node*, const Node*> Tree::top_bottom_nodes_of_subtree(std::string branch_id) const
{
    const Node* root = find_node(*this, [branch_id](const Node& aNode) -> bool { return aNode.branch_id == branch_id; });
    return std::make_pair(root != nullptr ? &find_first_leaf(*root) : nullptr, root != nullptr ? &find_last_leaf(*root) : nullptr);

} // Tree::top_bottom_nodes_of_subtree

// ----------------------------------------------------------------------

void Tree::print(std::ostream& out) const
{
    size_t indent = 0;
    auto p_name = [&out, &indent](const Node& aNode) {
        out << std::string(indent, ' ') << /* aNode.line_no << " -- " << */ aNode.display_name();
        if (aNode.edge_length >= 0)
            out << ':' << aNode.edge_length;
        out << std::endl;
    };
    auto p_subtree_pre = [&out, &indent](const Node& /*aNode*/) {
        out << std::string(indent, ' ') << '(' << /* ' ' << aNode.top << ' ' << aNode.bottom << */ std::endl;
        indent += 2;
    };
    auto p_subtree_post = [&out, &indent](const Node& aNode) {
        indent -= 2;
        out << std::string(indent, ' ') << ')';
        if (aNode.edge_length >= 0)
            out << ':' << aNode.edge_length;
        out << std::endl;
    };
    iterate(*this, p_name, p_subtree_pre, p_subtree_post);

} // Tree::print

// ----------------------------------------------------------------------

void Tree::print_edges(std::ostream& out) const
{
    std::map<double, size_t> edges; // edge length to number of occurences
    auto collect_edges = [&edges](const Node& aNode) -> void {
        auto iter_inserted = edges.insert(std::make_pair(aNode.edge_length, 1));
        if (!iter_inserted.second)
            ++iter_inserted.first->second;
    };
    iterate<const Node&>(*this, collect_edges, collect_edges);
    typedef std::pair<double, size_t> E;
    std::list<E> edges_l(edges.begin(), edges.end());
    edges_l.sort([](const E& a, const E& b) { return a.first < b.first; });
    for (auto e: edges_l) {
        out << e.first << " " << e.second << std::endl;
    }

} // Tree::print_edges

// ----------------------------------------------------------------------

void Tree::fix_labels()
{
    const std::list<std::pair<std::string, size_t>> to_remove {
        {"/HUMAN/", 6},
        {"(H3N2)/", 6},
        {"(H1N1)/", 6},
    };

    auto fix_human = [&to_remove](Node& aNode) -> void {
        for (auto e: to_remove) {
            auto const pos = aNode.name.find(e.first);
            if (pos != std::string::npos)
                aNode.name.erase(pos, e.second);
        }
    };
    iterate<Node&>(*this, fix_human);

} // Tree::fix_labels

// ----------------------------------------------------------------------

void load_from_json(Node& aNode, const json& j)
{
    if (j.count("edge_length"))
        aNode.edge_length = j["edge_length"];
    if (j.count("name"))
        aNode.name = j["name"];
    if (j.count("aa_at"))
        aNode.aa_at = j["aa_at"];
    if (j.count("subtree")) {
        auto subtree = j["subtree"];
        if (!subtree.is_array())
            throw std::runtime_error(std::string("cannot import tree: unrecognized subtree: ") + subtree.dump());
        for (auto e = subtree.begin(); e != subtree.end(); ++e) {
            Node node;
            load_from_json(node, *e);
            aNode.subtree.push_back(std::forward<Node>(node));
        }
        if (j.count("number_strains"))
            aNode.number_strains = j["number_strains"];
        if (j.count("id"))
            aNode.branch_id = j["id"];
    }
    else {
        if (j.count("date"))
            aNode.date = j["date"];
        if (j.count("continent"))
            aNode.continent = j["continent"];
        if (j.count("clades"))
            aNode.clades = static_cast<const std::vector<std::string>&>(j["clades"]);
    }

} // load_from_json

// ----------------------------------------------------------------------

json dump_to_json(const Node& aNode)
{
    json j = {{"edge_length", aNode.edge_length}};
    if (!aNode.name.empty())
        j["name"] = aNode.name;
    if (aNode.is_leaf()) {
        if (!aNode.date.empty())
            j["date"] = aNode.date.display();
        if (!aNode.continent.empty())
            j["continent"] = aNode.continent;
        if (!aNode.clades.empty())
            j["clades"] = aNode.clades;
    }
    else {
        std::vector<json> subtree;
        for (auto node = aNode.subtree.cbegin(); node != aNode.subtree.cend(); ++node) {
            subtree.push_back(dump_to_json(*node));
        }
        j["subtree"] = subtree;
        if (aNode.number_strains >= 0)
            j["number_strains"] = aNode.number_strains;
        if (!aNode.branch_id.empty())
            j["id"] = aNode.branch_id;
    }
    return j;
}

// ----------------------------------------------------------------------

void tree_from_json(Tree& aTree, std::string aSource, TreeImage& aTreeImage)
{
    auto j = json::parse(aSource);
    if (j["  version"] != TREE_JSON_DUMP_VERSION)
        throw std::runtime_error(std::string("cannot import tree: unsupported version") + j["version"].get<std::string>());
    load_from_json(aTree, j["tree"]);
    if (j.count("_settings"))
        aTreeImage.load_from_json(j["_settings"]);

} // tree_from_json

// ----------------------------------------------------------------------

void tree_to_json(Tree& aTree, std::string aFilename, std::string aCreator, const TreeImage& aTreeImage)
{
    char date_buf[100];
    std::time_t t = std::time(nullptr);
    std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M %Z", std::localtime(&t));

    json j = {
        {"  version", TREE_JSON_DUMP_VERSION},
        {"_settings", aTreeImage.dump_to_json()},
        {"updated", {{
                {"user", std::getenv("USER")},
                {"date", date_buf},
                {"creator", aCreator},
                }}},
        {"tree", dump_to_json(aTree)},
    };
    std::string output = j.dump(2);
    if (aFilename == "-") {
        std::cout << output << std::endl;
    }
    else {
        if (aFilename.substr(aFilename.size() - 3) == ".xz")
            output = xz_compress(output);
        int fd = open(aFilename.c_str(), O_WRONLY | O_CREAT, 0644);
        if (fd < 0)
            throw std::runtime_error(std::string("cannot write ") + aFilename + ": " + std::strerror(errno));
        write(fd, output.c_str(), output.size());
        close(fd);
    }

} // tree_to_json

// ----------------------------------------------------------------------
<commit_msg>bug fix<commit_after>#include <iostream>
#include <fstream>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <map>
#include <list>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>

#include "tree.hh"
#include "tree-image.hh"
#include "xz.hh"

// ----------------------------------------------------------------------

std::pair<double, size_t> Node::width_height() const
{
    size_t height = 0;
    double width = 0;
    if (is_leaf()) {
        ++height;
    }
    else {
        for (auto node = subtree.begin(); node != subtree.end(); ++node) {
            auto const wh = node->width_height();
            if (wh.first > width)
                width = wh.first;
            height += wh.second;
        }
    }
    return std::make_pair(width + edge_length, height);

} // Node::width_height

// ----------------------------------------------------------------------

int Node::months_from(const Date& aStart) const
{
    return date.empty() ? -1 : months_between_dates(aStart, date);

} // Node::month_no

// ----------------------------------------------------------------------

void Tree::analyse()
{
      // set line_no for each name node
    size_t current_line = 0;
    auto set_line_no = [&current_line](Node& aNode) {
        aNode.line_no = current_line;
        ++current_line;
    };
      // set top and bottom for each subtree node
    auto set_top_bottom = [](Node& aNode) {
        aNode.top = aNode.subtree.begin()->middle();
        aNode.bottom = aNode.subtree.rbegin()->middle();
    };
    iterate<Node&>(*this, set_line_no, &nope, set_top_bottom);

} // Tree::analyse

// ----------------------------------------------------------------------

std::pair<Date, Date> Tree::min_max_date() const
{
    Date min_date, max_date;
    auto min_max_date = [&min_date, &max_date](const Node& aNode) -> void {
        if (!aNode.date.empty()) {
            if (min_date.empty() || aNode.date < min_date)
                min_date = aNode.date;
            if (max_date.empty() || max_date < aNode.date)
                max_date = aNode.date;
        }
    };
    iterate<const Node&>(*this, min_max_date);
    return std::make_pair(min_date, max_date);

} // Tree::min_max_date

// ----------------------------------------------------------------------

std::pair<double, double> Tree::min_max_edge() const
{
    double min_edge = 1e99, max_edge = 0.0;
    auto min_max_edge = [&min_edge, &max_edge](const Node& aNode) -> void {
        if (aNode.edge_length > 0.0) {
            if (aNode.edge_length < min_edge)
                min_edge = aNode.edge_length;
            if (max_edge < aNode.edge_length)
                max_edge = aNode.edge_length;
        }
    };
    iterate<const Node&>(*this, min_max_edge, min_max_edge);
    return std::make_pair(min_edge, max_edge);

} // Tree::min_max_edge

// ----------------------------------------------------------------------

std::pair<const Node*, const Node*> Tree::top_bottom_nodes_of_subtree(std::string branch_id) const
{
    const Node* root = find_node(*this, [branch_id](const Node& aNode) -> bool { return aNode.branch_id == branch_id; });
    return std::make_pair(root != nullptr ? &find_first_leaf(*root) : nullptr, root != nullptr ? &find_last_leaf(*root) : nullptr);

} // Tree::top_bottom_nodes_of_subtree

// ----------------------------------------------------------------------

void Tree::print(std::ostream& out) const
{
    size_t indent = 0;
    auto p_name = [&out, &indent](const Node& aNode) {
        out << std::string(indent, ' ') << /* aNode.line_no << " -- " << */ aNode.display_name();
        if (aNode.edge_length >= 0)
            out << ':' << aNode.edge_length;
        out << std::endl;
    };
    auto p_subtree_pre = [&out, &indent](const Node& /*aNode*/) {
        out << std::string(indent, ' ') << '(' << /* ' ' << aNode.top << ' ' << aNode.bottom << */ std::endl;
        indent += 2;
    };
    auto p_subtree_post = [&out, &indent](const Node& aNode) {
        indent -= 2;
        out << std::string(indent, ' ') << ')';
        if (aNode.edge_length >= 0)
            out << ':' << aNode.edge_length;
        out << std::endl;
    };
    iterate(*this, p_name, p_subtree_pre, p_subtree_post);

} // Tree::print

// ----------------------------------------------------------------------

void Tree::print_edges(std::ostream& out) const
{
    std::map<double, size_t> edges; // edge length to number of occurences
    auto collect_edges = [&edges](const Node& aNode) -> void {
        auto iter_inserted = edges.insert(std::make_pair(aNode.edge_length, 1));
        if (!iter_inserted.second)
            ++iter_inserted.first->second;
    };
    iterate<const Node&>(*this, collect_edges, collect_edges);
    typedef std::pair<double, size_t> E;
    std::list<E> edges_l(edges.begin(), edges.end());
    edges_l.sort([](const E& a, const E& b) { return a.first < b.first; });
    for (auto e: edges_l) {
        out << e.first << " " << e.second << std::endl;
    }

} // Tree::print_edges

// ----------------------------------------------------------------------

void Tree::fix_labels()
{
    const std::list<std::pair<std::string, size_t>> to_remove {
        {"/HUMAN/", 6},
        {"(H3N2)/", 6},
        {"(H1N1)/", 6},
    };

    auto fix_human = [&to_remove](Node& aNode) -> void {
        for (auto e: to_remove) {
            auto const pos = aNode.name.find(e.first);
            if (pos != std::string::npos)
                aNode.name.erase(pos, e.second);
        }
    };
    iterate<Node&>(*this, fix_human);

} // Tree::fix_labels

// ----------------------------------------------------------------------

void load_from_json(Node& aNode, const json& j)
{
    if (j.count("edge_length"))
        aNode.edge_length = j["edge_length"];
    if (j.count("name"))
        aNode.name = j["name"];
    if (j.count("aa_at"))
        aNode.aa_at = j["aa_at"];
    if (j.count("subtree")) {
        auto subtree = j["subtree"];
        if (!subtree.is_array())
            throw std::runtime_error(std::string("cannot import tree: unrecognized subtree: ") + subtree.dump());
        for (auto e = subtree.begin(); e != subtree.end(); ++e) {
            Node node;
            load_from_json(node, *e);
            aNode.subtree.push_back(std::forward<Node>(node));
        }
        if (j.count("number_strains"))
            aNode.number_strains = j["number_strains"];
        if (j.count("id"))
            aNode.branch_id = j["id"];
    }
    else {
        if (j.count("date"))
            aNode.date = j["date"];
        if (j.count("continent"))
            aNode.continent = j["continent"];
        if (j.count("clades"))
            aNode.clades = static_cast<const std::vector<std::string>&>(j["clades"]);
    }

} // load_from_json

// ----------------------------------------------------------------------

json dump_to_json(const Node& aNode)
{
    json j = {{"edge_length", aNode.edge_length}};
    if (!aNode.name.empty())
        j["name"] = aNode.name;
    if (aNode.is_leaf()) {
        if (!aNode.date.empty())
            j["date"] = aNode.date.display();
        if (!aNode.continent.empty())
            j["continent"] = aNode.continent;
        if (!aNode.clades.empty())
            j["clades"] = aNode.clades;
    }
    else {
        std::vector<json> subtree;
        for (auto node = aNode.subtree.cbegin(); node != aNode.subtree.cend(); ++node) {
            subtree.push_back(dump_to_json(*node));
        }
        j["subtree"] = subtree;
        if (aNode.number_strains >= 0)
            j["number_strains"] = aNode.number_strains;
        if (!aNode.branch_id.empty())
            j["id"] = aNode.branch_id;
    }
    return j;
}

// ----------------------------------------------------------------------

void tree_from_json(Tree& aTree, std::string aSource, TreeImage& aTreeImage)
{
    auto j = json::parse(aSource);
    if (j["  version"] != TREE_JSON_DUMP_VERSION)
        throw std::runtime_error(std::string("cannot import tree: unsupported version") + j["version"].get<std::string>());
    load_from_json(aTree, j["tree"]);
    if (j.count("_settings"))
        aTreeImage.load_from_json(j["_settings"]);

} // tree_from_json

// ----------------------------------------------------------------------

void tree_to_json(Tree& aTree, std::string aFilename, std::string aCreator, const TreeImage& aTreeImage)
{
    char date_buf[100];
    std::time_t t = std::time(nullptr);
    std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M %Z", std::localtime(&t));

    json j = {
        {"  version", TREE_JSON_DUMP_VERSION},
        {"_settings", aTreeImage.dump_to_json()},
        {"updated", {{
                {"user", std::getenv("USER")},
                {"date", date_buf},
                {"creator", aCreator},
                }}},
        {"tree", dump_to_json(aTree)},
    };
    std::string output = j.dump(2);
    if (aFilename == "-") {
        std::cout << output << std::endl;
    }
    else {
        if (aFilename.substr(aFilename.size() - 3) == ".xz")
            output = xz_compress(output);
        int fd = open(aFilename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if (fd < 0)
            throw std::runtime_error(std::string("cannot write ") + aFilename + ": " + std::strerror(errno));
        write(fd, output.c_str(), output.size());
        close(fd);
    }

} // tree_to_json

// ----------------------------------------------------------------------
<|endoftext|>


<commit_before>// Copyright 2013 Tanel Lebedev

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "./kopsik_api.h"
#include "./https_client.h"

#include "Poco/FileStream.h"
#include "Poco/File.h"

#define TESTDB "test.db"
#define ERRLEN 1024

namespace kopsik {

    class MockHTTPSClient : public HTTPSClient {
    public:
        MOCK_METHOD0(ListenToWebsocket, kopsik::error());
        MOCK_METHOD5(PostJSON, kopsik::error(
            std::string relative_url,
            std::string json,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
        MOCK_METHOD4(GetJSON, kopsik::error(
            std::string relative_url,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
    };

    TEST(KopsikApiTest, kopsik_context_init) {
        KopsikContext *ctx = kopsik_context_init();
        ASSERT_TRUE(ctx);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_version) {
        int major = 0;
        int minor = 0;
        int patch = 0;
        kopsik_version(&major, &minor, &patch);
        ASSERT_TRUE(major || minor || patch);
    }

    TEST(KopsikApiTest, kopsik_set_proxy) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_proxy(ctx, "localhost", 8000, "johnsmith", "secret");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_set_db_path) {
        KopsikContext *ctx = kopsik_context_init();
        {
            Poco::File f(TESTDB);
            if (f.exists()) f.remove(false);
        }
        kopsik_set_db_path(ctx, TESTDB);
        kopsik_context_clear(ctx);
        Poco::File f(TESTDB);
        ASSERT_TRUE(f.exists());
    }

    TEST(KopsikApiTest, kopsik_set_log_path) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_log_path(ctx, "test.log");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_user_init) {
        KopsikUser *user = kopsik_user_init();
        ASSERT_TRUE(user);
        kopsik_user_clear(user);
    }

    TEST(KopsikApiTest, kopsik_set_api_token) {
        KopsikContext *ctx = kopsik_context_init();
        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_set_api_token(ctx, err, ERRLEN, "token"));
        const int kMaxStrLen = 10;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("token", std::string(str));
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_lifecycle) {
        KopsikContext *ctx = kopsik_context_init();

        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);

        kopsik::HTTPSClient *client =
            reinterpret_cast<HTTPSClient *>(ctx->https_client);
        delete client;
        MockHTTPSClient *mock_client = new MockHTTPSClient();
        ctx->https_client = mock_client;

        Poco::FileStream fis("testdata/me.json", std::ios::binary);
        std::stringstream ss;
        ss << fis.rdbuf();
        fis.close();
        std::string json = ss.str();

        // Login
        EXPECT_CALL(*mock_client, GetJSON(
            std::string("/api/v8/me?with_related_data=true"),
            std::string("foo@bar.com"),
            std::string("secret"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<3>(json),
            testing::Return("")));
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_login(
            ctx,
            err, ERRLEN,
            "foo@bar.com", "secret"));

        // We should have the API token now
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("30eb0ae954b536d2f6628f7fec47beb6", std::string(str));

        // We should have current user now
        KopsikUser *user = kopsik_user_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_current_user(ctx, err, ERRLEN, user));
        ASSERT_EQ((unsigned int)10471231, user->ID);
        ASSERT_EQ(std::string("John Smith"), std::string(user->Fullname));
        kopsik_user_clear(user);

        // Count time entry items before start. It should be 3, since
        // there are 3 time entries in the me.json file we're using:
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_EQ((unsigned int)3, list->Length);
        int number_of_items = list->Length;
        kopsik_time_entry_view_item_list_clear(list);

        // Start tracking
        KopsikTimeEntryViewItem *item = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_start(ctx, err, ERRLEN, "Test", item));
        ASSERT_EQ(std::string("Test"), std::string(item->Description));
        kopsik_time_entry_view_item_clear(item);

        // We should now have a running time entry
        int is_tracking = 0;
        KopsikTimeEntryViewItem *running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_TRUE(is_tracking);
        ASSERT_GT(0, running->DurationInSeconds);
        ASSERT_EQ(std::string("Test"), std::string(running->Description));
        ASSERT_FALSE(running->Project);
        ASSERT_TRUE(running->Duration);
        ASSERT_FALSE(running->Color);
        ASSERT_TRUE(running->GUID);
        std::string GUID(running->GUID);
        kopsik_time_entry_view_item_clear(running);

        // The running time entry should *not* be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 0, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // Stop the time entry
        KopsikTimeEntryViewItem *stopped = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_stop(ctx, err, ERRLEN, stopped));
        ASSERT_EQ(std::string("Test"), std::string(stopped->Description));
        std::string dirty_guid(stopped->GUID);
        kopsik_time_entry_view_item_clear(stopped);

        // Now the stopped time entry should be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 1, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // We should no longer get a running time entry from API.
        is_tracking = 0;
        running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_FALSE(is_tracking);
        kopsik_time_entry_view_item_clear(running);

        // We started and stopped one time entry.
        // This means we should have one dirty model now.
        KopsikPushableModelStats stats;
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Push changes
        std::stringstream response_body;
        response_body
            << "["
            << "{"
            << "\"status\": 200,"
            << "\"guid\": \"" << dirty_guid << "\","
            << "\"content_type\": \"application/json\","
            << "\"body\": \""
                << "{\"data\": {\"id\": 123456789, \"ui_modified_at\": "
                << time(0) << "}}\""
            << "}"
            << "]";
        std::string response_json = response_body.str();
        EXPECT_CALL(*mock_client, PostJSON(
            std::string("/api/v8/batch_updates"),
            testing::An<std::string>(),
            std::string("30eb0ae954b536d2f6628f7fec47beb6"),
            std::string("api_token"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<4>(response_json),
            testing::Return("")));

        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_push(
            ctx, err, ERRLEN));

        // Check that no dirty models are left.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)0, stats.TimeEntries);

        // Continue the time entry we created in the start.
        KopsikTimeEntryViewItem *continued =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_continue(
            ctx, err, ERRLEN, GUID.c_str(), continued));
        ASSERT_NE(std::string(GUID), std::string(continued->GUID));
        ASSERT_FALSE(std::string(continued->Duration).empty());
        ASSERT_GT(0, continued->DurationInSeconds);
        kopsik_time_entry_view_item_clear(continued);

        // We should now once again have a dirty model.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Get time entry view using GUID
        int was_found = 0;
        KopsikTimeEntryViewItem *found = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, dirty_guid.c_str(), found, &was_found));
        ASSERT_EQ(dirty_guid, std::string(found->GUID));
        ASSERT_TRUE(was_found);
        kopsik_time_entry_view_item_clear(found);

        // Ask for a non-existant time entry
        KopsikTimeEntryViewItem *nonexistant =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, "bad guid", nonexistant, &was_found));
        ASSERT_FALSE(nonexistant->GUID);
        ASSERT_FALSE(was_found);
        kopsik_time_entry_view_item_clear(nonexistant);

        // Delete the time entry we created in the start.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_delete_time_entry(
            ctx, err, ERRLEN, GUID.c_str()));

        // We shouldnt be able to retrieve this time entry now in list.
        KopsikTimeEntryViewItemList *visible =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, visible));
        for (unsigned int i = 0; i < visible->Length; i++) {
            KopsikTimeEntryViewItem *n = visible->ViewItems[i];
            ASSERT_FALSE(std::string(n->GUID) == GUID);
        }
        kopsik_time_entry_view_item_list_clear(visible);

        // Log out
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_logout(ctx, err, ERRLEN));

        // Check that we have no API token after user logged out.
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("", std::string(str));

        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_init) {
        KopsikTimeEntryViewItem *te = kopsik_time_entry_view_item_init();
        ASSERT_TRUE(te);
        kopsik_time_entry_view_item_clear(te);
    }

    TEST(KopsikApiTest, kopsik_format_duration_in_seconds) {
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        kopsik_format_duration_in_seconds(10, str, kMaxStrLen);
        ASSERT_EQ("00:00:10", std::string(str));
        kopsik_format_duration_in_seconds(60, str, kMaxStrLen);
        ASSERT_EQ("00:01:00", std::string(str));
        kopsik_format_duration_in_seconds(65, str, kMaxStrLen);
        ASSERT_EQ("00:01:05", std::string(str));
        kopsik_format_duration_in_seconds(3600, str, kMaxStrLen);
        ASSERT_EQ("01:00:00", std::string(str));
        kopsik_format_duration_in_seconds(5400, str, kMaxStrLen);
        ASSERT_EQ("01:30:00", std::string(str));
        kopsik_format_duration_in_seconds(5410, str, kMaxStrLen);
        ASSERT_EQ("01:30:10", std::string(str));
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_list_init) {
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_TRUE(list);
        kopsik_time_entry_view_item_list_clear(list);
    }

}  // namespace kopsik
<commit_msg>Fix test mock<commit_after>// Copyright 2013 Tanel Lebedev

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "./kopsik_api.h"
#include "./https_client.h"

#include "Poco/FileStream.h"
#include "Poco/File.h"

#define TESTDB "test.db"
#define ERRLEN 1024

namespace kopsik {

    class MockHTTPSClient : public HTTPSClient {
    public:
        MOCK_METHOD0(ListenToWebsocket, kopsik::error());
        MOCK_METHOD5(PostJSON, kopsik::error(
            std::string relative_url,
            std::string json,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
        MOCK_METHOD4(GetJSON, kopsik::error(
            std::string relative_url,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
    };

    TEST(KopsikApiTest, kopsik_context_init) {
        KopsikContext *ctx = kopsik_context_init();
        ASSERT_TRUE(ctx);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_version) {
        int major = 0;
        int minor = 0;
        int patch = 0;
        kopsik_version(&major, &minor, &patch);
        ASSERT_TRUE(major || minor || patch);
    }

    TEST(KopsikApiTest, kopsik_set_proxy) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_proxy(ctx, "localhost", 8000, "johnsmith", "secret");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_set_db_path) {
        KopsikContext *ctx = kopsik_context_init();
        {
            Poco::File f(TESTDB);
            if (f.exists()) f.remove(false);
        }
        kopsik_set_db_path(ctx, TESTDB);
        kopsik_context_clear(ctx);
        Poco::File f(TESTDB);
        ASSERT_TRUE(f.exists());
    }

    TEST(KopsikApiTest, kopsik_set_log_path) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_log_path(ctx, "test.log");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_user_init) {
        KopsikUser *user = kopsik_user_init();
        ASSERT_TRUE(user);
        kopsik_user_clear(user);
    }

    TEST(KopsikApiTest, kopsik_set_api_token) {
        KopsikContext *ctx = kopsik_context_init();
        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_set_api_token(ctx, err, ERRLEN, "token"));
        const int kMaxStrLen = 10;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("token", std::string(str));
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_lifecycle) {
        KopsikContext *ctx = kopsik_context_init();

        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);

        kopsik::HTTPSClient *client =
            reinterpret_cast<HTTPSClient *>(ctx->https_client);
        delete client;
        MockHTTPSClient *mock_client = new MockHTTPSClient();
        ctx->https_client = mock_client;

        Poco::FileStream fis("testdata/me.json", std::ios::binary);
        std::stringstream ss;
        ss << fis.rdbuf();
        fis.close();
        std::string json = ss.str();

        // Login
        EXPECT_CALL(*mock_client, GetJSON(
            std::string("/api/v8/me?app_name=kopsik&with_related_data=true"),
            std::string("foo@bar.com"),
            std::string("secret"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<3>(json),
            testing::Return("")));
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_login(
            ctx,
            err, ERRLEN,
            "foo@bar.com", "secret"));

        // We should have the API token now
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("30eb0ae954b536d2f6628f7fec47beb6", std::string(str));

        // We should have current user now
        KopsikUser *user = kopsik_user_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_current_user(ctx, err, ERRLEN, user));
        ASSERT_EQ((unsigned int)10471231, user->ID);
        ASSERT_EQ(std::string("John Smith"), std::string(user->Fullname));
        kopsik_user_clear(user);

        // Count time entry items before start. It should be 3, since
        // there are 3 time entries in the me.json file we're using:
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_EQ((unsigned int)3, list->Length);
        int number_of_items = list->Length;
        kopsik_time_entry_view_item_list_clear(list);

        // Start tracking
        KopsikTimeEntryViewItem *item = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_start(ctx, err, ERRLEN, "Test", item));
        ASSERT_EQ(std::string("Test"), std::string(item->Description));
        kopsik_time_entry_view_item_clear(item);

        // We should now have a running time entry
        int is_tracking = 0;
        KopsikTimeEntryViewItem *running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_TRUE(is_tracking);
        ASSERT_GT(0, running->DurationInSeconds);
        ASSERT_EQ(std::string("Test"), std::string(running->Description));
        ASSERT_FALSE(running->Project);
        ASSERT_TRUE(running->Duration);
        ASSERT_FALSE(running->Color);
        ASSERT_TRUE(running->GUID);
        std::string GUID(running->GUID);
        kopsik_time_entry_view_item_clear(running);

        // The running time entry should *not* be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 0, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // Stop the time entry
        KopsikTimeEntryViewItem *stopped = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_stop(ctx, err, ERRLEN, stopped));
        ASSERT_EQ(std::string("Test"), std::string(stopped->Description));
        std::string dirty_guid(stopped->GUID);
        kopsik_time_entry_view_item_clear(stopped);

        // Now the stopped time entry should be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 1, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // We should no longer get a running time entry from API.
        is_tracking = 0;
        running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_FALSE(is_tracking);
        kopsik_time_entry_view_item_clear(running);

        // We started and stopped one time entry.
        // This means we should have one dirty model now.
        KopsikPushableModelStats stats;
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Push changes
        std::stringstream response_body;
        response_body
            << "["
            << "{"
            << "\"status\": 200,"
            << "\"guid\": \"" << dirty_guid << "\","
            << "\"content_type\": \"application/json\","
            << "\"body\": \""
                << "{\"data\": {\"id\": 123456789, \"ui_modified_at\": "
                << time(0) << "}}\""
            << "}"
            << "]";
        std::string response_json = response_body.str();
        EXPECT_CALL(*mock_client, PostJSON(
            std::string("/api/v8/batch_updates"),
            testing::An<std::string>(),
            std::string("30eb0ae954b536d2f6628f7fec47beb6"),
            std::string("api_token"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<4>(response_json),
            testing::Return("")));

        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_push(
            ctx, err, ERRLEN));

        // Check that no dirty models are left.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)0, stats.TimeEntries);

        // Continue the time entry we created in the start.
        KopsikTimeEntryViewItem *continued =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_continue(
            ctx, err, ERRLEN, GUID.c_str(), continued));
        ASSERT_NE(std::string(GUID), std::string(continued->GUID));
        ASSERT_FALSE(std::string(continued->Duration).empty());
        ASSERT_GT(0, continued->DurationInSeconds);
        kopsik_time_entry_view_item_clear(continued);

        // We should now once again have a dirty model.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Get time entry view using GUID
        int was_found = 0;
        KopsikTimeEntryViewItem *found = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, dirty_guid.c_str(), found, &was_found));
        ASSERT_EQ(dirty_guid, std::string(found->GUID));
        ASSERT_TRUE(was_found);
        kopsik_time_entry_view_item_clear(found);

        // Ask for a non-existant time entry
        KopsikTimeEntryViewItem *nonexistant =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, "bad guid", nonexistant, &was_found));
        ASSERT_FALSE(nonexistant->GUID);
        ASSERT_FALSE(was_found);
        kopsik_time_entry_view_item_clear(nonexistant);

        // Delete the time entry we created in the start.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_delete_time_entry(
            ctx, err, ERRLEN, GUID.c_str()));

        // We shouldnt be able to retrieve this time entry now in list.
        KopsikTimeEntryViewItemList *visible =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, visible));
        for (unsigned int i = 0; i < visible->Length; i++) {
            KopsikTimeEntryViewItem *n = visible->ViewItems[i];
            ASSERT_FALSE(std::string(n->GUID) == GUID);
        }
        kopsik_time_entry_view_item_list_clear(visible);

        // Log out
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_logout(ctx, err, ERRLEN));

        // Check that we have no API token after user logged out.
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("", std::string(str));

        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_init) {
        KopsikTimeEntryViewItem *te = kopsik_time_entry_view_item_init();
        ASSERT_TRUE(te);
        kopsik_time_entry_view_item_clear(te);
    }

    TEST(KopsikApiTest, kopsik_format_duration_in_seconds) {
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        kopsik_format_duration_in_seconds(10, str, kMaxStrLen);
        ASSERT_EQ("00:00:10", std::string(str));
        kopsik_format_duration_in_seconds(60, str, kMaxStrLen);
        ASSERT_EQ("00:01:00", std::string(str));
        kopsik_format_duration_in_seconds(65, str, kMaxStrLen);
        ASSERT_EQ("00:01:05", std::string(str));
        kopsik_format_duration_in_seconds(3600, str, kMaxStrLen);
        ASSERT_EQ("01:00:00", std::string(str));
        kopsik_format_duration_in_seconds(5400, str, kMaxStrLen);
        ASSERT_EQ("01:30:00", std::string(str));
        kopsik_format_duration_in_seconds(5410, str, kMaxStrLen);
        ASSERT_EQ("01:30:10", std::string(str));
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_list_init) {
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_TRUE(list);
        kopsik_time_entry_view_item_list_clear(list);
    }

}  // namespace kopsik
<|endoftext|>


<commit_before>#include<stdio.h>
#include <GLUT/glut.h>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
float toradian(float degree){
    return (3.14159/180)*degree;
}

void draw_rectangle(float x, float y, float w, float h, int fill){
    if (fill)
        glBegin(GL_POLYGON);
    else
        glBegin(GL_LINE_LOOP);

        glVertex2f(x, y);
        glVertex2f(x+w, y);
        glVertex2f(x+w, y+h);
        glVertex2f(x, y+h);
    glEnd();
    glFlush();

}

void draw_circle(float x, float y, float r, int fill){
    float i;
    float x_cord, y_cord;
    if (fill)
        glBegin(GL_POLYGON);
    else
        glBegin(GL_POINTS);

    for (i = 0; i < 360; i+= 0.6){
        x_cord = x + r*cos(toradian((float)i));
        y_cord = y + r*sin(toradian((float)i));
        glVertex2f(x_cord, y_cord);
    }
    glEnd();
    glFlush();
}

class mountain{
public:
   mountain(){
    printf("object created\n" );
  }
  void draw_mountain() {
    float a = 300,r = 0.15;
    for(int i =0;i<1000;i++){
      float width_gp = a+(i-1)*r;
      // printf("%f\n",width_gp);
      if(1000.0-1*i < 600 && 1000.0-1*i > 580){
        int factors = (20-(i*2)%20);
        // printf("colored\n");
        // glColor3ub(255,163,245);
        a = a + factors;
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
      else if(1000.0-1*i < 700 && 1000.0-1*i > 680){
        printf("colored\n");
        glColor3ub(255,163,245);
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
      else {
        glColor3ub(161,104,0);
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
    }
  }
  void draw_road() {
    float a = 300,r = 0.15,i,width_gp;
    for(i =590; i<610;i++) {
      width_gp = a+(i-1)*r;
      glColor3ub(0,0,0);
      draw_rectangle(width_gp-30,i,180-(i-590),1,1);
    }
    printf("final number:(%f,%f)\n",width_gp-30+180-(i-590),i);
  }
  void draw_plastic() {
    int x = 521,y = 610;
    glBegin(GL_QUADS);
      glVertex2f(x,y);
      glVertex2f(x,y+5);
      glVertex2f(x-5,y+15);
      glVertex2f(x-5,y+35);
      glVertex2f(x+7,y+35);
      glVertex2f(x+7,y+15);
      glVertex2f(x+2,y+15);
      glVertex2f(x,y);
      glEnd();
  }
  void draw_fense() {
    int x = 559,y = 590;
    // glColor3ub(255,165,0);

    glColor3ub(255,255,255);
    glBegin(GL_POLYGON);
      glVertex2f(x,y);
      glVertex2f(x,y+5);
      glVertex2f(x-5,y+5);
      glVertex2f(x-5,y+25);
      glVertex2f(x+7,y+25);
      glVertex2f(x+7,y+5);
      glVertex2f(x+2,y+5);
      glVertex2f(x,y);
    glEnd();
    glColor3ub(255,165,0);
    glBegin(GL_QUADS);
      glVertex2f(x-5,y+15);
      glVertex2f(x+7,y+25);
      glVertex2f(x+7,y+20);
      glVertex2f(x-5,y+20);
    glEnd();
    glBegin(GL_QUADS);
      glVertex2f(x-5,y+15-7);
      glVertex2f(x+7,y+25-7);
      glVertex2f(x+7,y+20-7);
      glVertex2f(x-5,y+20-7);
    glEnd();
  }
  void sky_full_of_stars() {
    glColor3ub(255,255,255);
    glPointSize(1);
    glBegin(GL_POINTS);

    for(int i=0;i<1000;i++){

      int x = rand();
      int y = rand();
      x = x%1000;
      y = y%1000;
      if(x>350 && y>650) {
        glVertex2f(x,y);
        printf("point added\n" );
      }
      else if(x>650){
        glVertex2f(x,y);
        printf("point added\n" );
      }
    }
    glEnd();
    draw_circle(900,900,25,1);
    glColor3f(0.25,0.25,0.25);
    draw_circle(905,915,25,1);
  }
};

void init()
{
	glClearColor(0.529,0.808,0.98,1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1000,0,1000);
}
void myReshape(int w,int h)
{
  printf("resized\n w=%d,h=%d",w,h);
	glClearColor(0.529,0.808,0.98,1.0);
	//glClearColor(0.50,0.88,0.96,0);
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(w<=h)
		glOrtho(0,1000,0*(GLfloat)h/(GLfloat)w,1000*(GLfloat)h/(GLfloat)w,0,1000);
	else
		glOrtho(0*(GLfloat)w/(GLfloat)h,1000*(GLfloat)w/(GLfloat)h,0,1000,0,1000);
	glMatrixMode(GL_MODELVIEW);
	glutPostRedisplay();

}
void display_scene3(){
  mountain m;
  glClearColor(0.25,0.25,0.25,0);
  glClear(GL_COLOR_BUFFER_BIT);
  m.draw_mountain();
  m.draw_road();
  m.draw_fense();
  m.sky_full_of_stars();
  printf("yolo\n");
  glFlush();
  glutSwapBuffers();
}
void mouse(int button, int state,int x, int y){
  printf("called\n");
  if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) {
    printf("x: %d, y: %d",x,y);
  }
}
int main(int argc,char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
	glutInitWindowSize(1000,1000);
	glutCreateWindow("Scene1");
  glutMouseFunc(mouse);
	init();
	//glutReshapeFunc(myReshape);
	glutDisplayFunc(display_scene3);
	glutMainLoop();

}
<commit_msg>scene 6 cloned<commit_after>#include<stdio.h>
#include <GLUT/glut.h>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
float toradian(float degree){
    return (3.14159/180)*degree;
}

void draw_rectangle(float x, float y, float w, float h, int fill){
    if (fill)
        glBegin(GL_POLYGON);
    else
        glBegin(GL_LINE_LOOP);

        glVertex2f(x, y);
        glVertex2f(x+w, y);
        glVertex2f(x+w, y+h);
        glVertex2f(x, y+h);
    glEnd();
    glFlush();

}

void draw_circle(float x, float y, float r, int fill){
    float i;
    float x_cord, y_cord;
    if (fill)
        glBegin(GL_POLYGON);
    else
        glBegin(GL_POINTS);

    for (i = 0; i < 360; i+= 0.6){
        x_cord = x + r*cos(toradian((float)i));
        y_cord = y + r*sin(toradian((float)i));
        glVertex2f(x_cord, y_cord);
    }
    glEnd();
    glFlush();
}

class mountain{
public:
   mountain(){
    printf("object created\n" );
  }
  void draw_mountain() {
    float a = 300,r = 0.15;
    for(int i =0;i<1000;i++){
      float width_gp = a+(i-1)*r;
      // printf("%f\n",width_gp);
      if(1000.0-1*i < 600 && 1000.0-1*i > 580){
        int factors = (20-(i*2)%20);
        // printf("colored\n");
        // glColor3ub(255,163,245);
        a = a + factors;
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
      else if(1000.0-1*i < 700 && 1000.0-1*i > 680){
        printf("colored\n");
        glColor3ub(255,163,245);
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
      else {
        glColor3ub(161,104,0);
        draw_rectangle(0.0,1000.0-1*i,width_gp,10.0,1);
      }
    }
  }
  void draw_road() {
    float a = 300,r = 0.15,i,width_gp;
    for(i =590; i<610;i++) {
      width_gp = a+(i-1)*r;
      glColor3ub(0,0,0);
      draw_rectangle(width_gp-30,i,180-(i-590),1,1);
    }
    printf("final number:(%f,%f)\n",width_gp-30+180-(i-590),i);
  }
  void draw_plastic() {
    int x = 521,y = 610;
    glBegin(GL_QUADS);
      glVertex2f(x,y);
      glVertex2f(x,y+5);
      glVertex2f(x-5,y+15);
      glVertex2f(x-5,y+35);
      glVertex2f(x+7,y+35);
      glVertex2f(x+7,y+15);
      glVertex2f(x+2,y+15);
      glVertex2f(x,y);
      glEnd();
  }
  void draw_fense() {
    int x = 559,y = 590;
    // glColor3ub(255,165,0);

    glColor3ub(255,255,255);
    glBegin(GL_POLYGON);
      glVertex2f(x,y);
      glVertex2f(x,y+5);
      glVertex2f(x-5,y+5);
      glVertex2f(x-5,y+25);
      glVertex2f(x+7,y+25);
      glVertex2f(x+7,y+5);
      glVertex2f(x+2,y+5);
      glVertex2f(x,y);
    glEnd();
    glColor3ub(255,165,0);
    glBegin(GL_QUADS);
      glVertex2f(x-5,y+15);
      glVertex2f(x+7,y+25);
      glVertex2f(x+7,y+20);
      glVertex2f(x-5,y+20);
    glEnd();
    glBegin(GL_QUADS);
      glVertex2f(x-5,y+15-7);
      glVertex2f(x+7,y+25-7);
      glVertex2f(x+7,y+20-7);
      glVertex2f(x-5,y+20-7);
    glEnd();
  }
  void sky_full_of_stars() {
    glColor3ub(255,255,255);
    glPointSize(1.5);
    glBegin(GL_POINTS);

    for(int i=0;i<1000;i++){

      int x = rand();
      int y = rand();
      x = x%1000;
      y = y%1000;
      if(x>350 && y>650) {
        glVertex2f(x,y);
        printf("point added\n" );
      }
      else if(x>650){
        glVertex2f(x,y);
        printf("point added\n" );
      }
    }
    glEnd();
    draw_circle(900,900,25,1);
    glColor3f(0.25,0.25,0.25);
    draw_circle(905,915,25,1);
  }
};

void init()
{
	glClearColor(0.529,0.808,0.98,1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1000,0,1000);
}
void myReshape(int w,int h)
{
  printf("resized\n w=%d,h=%d",w,h);
	glClearColor(0.529,0.808,0.98,1.0);
	//glClearColor(0.50,0.88,0.96,0);
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(w<=h)
		glOrtho(0,1000,0*(GLfloat)h/(GLfloat)w,1000*(GLfloat)h/(GLfloat)w,0,1000);
	else
		glOrtho(0*(GLfloat)w/(GLfloat)h,1000*(GLfloat)w/(GLfloat)h,0,1000,0,1000);
	glMatrixMode(GL_MODELVIEW);
	glutPostRedisplay();

}
void display_scene3(){
  mountain m;
  glClearColor(0.25,0.25,0.25,0);
  glClear(GL_COLOR_BUFFER_BIT);
  m.draw_mountain();
  m.draw_road();
  m.draw_fense();
  m.sky_full_of_stars();
  printf("yolo\n");
  glFlush();
  glutSwapBuffers();
}
void mouse(int button, int state,int x, int y){
  printf("called\n");
  if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) {
    printf("x: %d, y: %d",x,y);
  }
}
int main(int argc,char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
	glutInitWindowSize(1000,1000);
	glutCreateWindow("Scene1");
  glutMouseFunc(mouse);
	init();
	//glutReshapeFunc(myReshape);
	glutDisplayFunc(display_scene3);
	glutMainLoop();

}
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <ch_ethz_tell_Schema.h>
#include <tellstore/Record.hpp>
#include <crossbow/enum_underlying.hpp>

#include "helpers.hpp"

jlong Java_ch_ethz_tell_Schema_construct(JNIEnv*, jobject) {
    return reinterpret_cast<long>(new tell::store::Schema());
}

void Java_ch_ethz_tell_Schema_destruct(JNIEnv*, jobject, jlong self) {
    delete reinterpret_cast<tell::store::Schema*>(self);
}

jboolean Java_ch_ethz_tell_Schema_addFieldImpl(JNIEnv* env, jobject, jlong self, jshort type, jstring jname, jboolean notNull) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    crossbow::string name = to_string(env, jname);
    uint16_t ftU = type;
    return s->addField(crossbow::from_underlying<tell::store::FieldType>(ftU), name, notNull);
}

jboolean Java_ch_ethz_tell_Schema_allNotNullImpl(JNIEnv*, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->allNotNull();
}

namespace {
jintArray toIntArray(JNIEnv* env, const std::vector<tell::store::Field>& fields) {
    auto res = env->NewIntArray(fields.size());
    std::unique_ptr<jint[]> tmp(new jint[fields.size()]);
    for (unsigned i = 0; i < fields.size(); ++i) {
        tmp[i] = crossbow::to_underlying(fields[i].type());
    }
    env->SetIntArrayRegion(res, 0, fields.size(), tmp.get());
    return res;
}

}

jintArray Java_ch_ethz_tell_Schema_fixedSizeFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->fixedSizeFields());
}

jintArray Java_ch_ethz_tell_Schema_variableSizedFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->varSizeFields());
}

jshort Java_ch_ethz_tell_Schema_idOfImpl (JNIEnv* env, jobject, jlong self, jstring columnName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->idOf(to_string(env, columnName));
}

jshort Java_ch_ethz_tell_Schema_typeOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return static_cast<short>(field.type());
}

jboolean Java_ch_ethz_tell_Schema_nullabiltyOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return field.isNotNull();
}

jobjectArray Java_ch_ethz_tell_Schema_getFieldNamesImpl (JNIEnv* env, jobject, jlong self) {
    std::vector<std::string> resultVec;
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    for (auto &field: s->fixedSizeFields())
        resultVec.emplace_back(field.name().c_str());
    for (auto &field: s->varSizeFields())
        resultVec.emplace_back(field.name().c_str());

    auto cls = env->FindClass("java/lang/String");
    auto init = env->NewStringUTF("");
    auto result = env->NewObjectArray(resultVec.size(), cls, init);
    for (unsigned i = 0; i < resultVec.size(); ++i) {
        env->SetObjectArrayElement(result, static_cast<int>(i), env->NewStringUTF(resultVec[i].c_str()));
    }
    return result;
}

<commit_msg>hopefully fixed bug swith string array<commit_after>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <ch_ethz_tell_Schema.h>
#include <tellstore/Record.hpp>
#include <crossbow/enum_underlying.hpp>

#include "helpers.hpp"

jlong Java_ch_ethz_tell_Schema_construct(JNIEnv*, jobject) {
    return reinterpret_cast<long>(new tell::store::Schema());
}

void Java_ch_ethz_tell_Schema_destruct(JNIEnv*, jobject, jlong self) {
    delete reinterpret_cast<tell::store::Schema*>(self);
}

jboolean Java_ch_ethz_tell_Schema_addFieldImpl(JNIEnv* env, jobject, jlong self, jshort type, jstring jname, jboolean notNull) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    crossbow::string name = to_string(env, jname);
    uint16_t ftU = type;
    return s->addField(crossbow::from_underlying<tell::store::FieldType>(ftU), name, notNull);
}

jboolean Java_ch_ethz_tell_Schema_allNotNullImpl(JNIEnv*, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->allNotNull();
}

namespace {
jintArray toIntArray(JNIEnv* env, const std::vector<tell::store::Field>& fields) {
    auto res = env->NewIntArray(fields.size());
    std::unique_ptr<jint[]> tmp(new jint[fields.size()]);
    for (unsigned i = 0; i < fields.size(); ++i) {
        tmp[i] = crossbow::to_underlying(fields[i].type());
    }
    env->SetIntArrayRegion(res, 0, fields.size(), tmp.get());
    return res;
}

}

jintArray Java_ch_ethz_tell_Schema_fixedSizeFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->fixedSizeFields());
}

jintArray Java_ch_ethz_tell_Schema_variableSizedFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->varSizeFields());
}

jshort Java_ch_ethz_tell_Schema_idOfImpl (JNIEnv* env, jobject, jlong self, jstring columnName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->idOf(to_string(env, columnName));
}

jshort Java_ch_ethz_tell_Schema_typeOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return static_cast<short>(field.type());
}

jboolean Java_ch_ethz_tell_Schema_nullabiltyOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return field.isNotNull();
}

jobjectArray Java_ch_ethz_tell_Schema_getFieldNamesImpl (JNIEnv* env, jobject, jlong self) {
    std::vector<const char *> resultVec;
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    for (auto &field: s->fixedSizeFields())
        resultVec.emplace_back(field.name().c_str());
    for (auto &field: s->varSizeFields())
        resultVec.emplace_back(field.name().c_str());

    auto cls = env->FindClass("java/lang/String");
    auto init = env->NewStringUTF("");
    auto result = env->NewObjectArray(resultVec.size(), cls, init);
    for (unsigned i = 0; i < resultVec.size(); ++i) {
        env->SetObjectArrayElement(result, static_cast<int>(i), env->NewStringUTF(resultVec[i]));
    }
    return result;
}

<|endoftext|>


<commit_before>#include "WindowUtility.h"
#include <tlhelp32.h>
#include <psapi.h>
#include <shlobj.h>

HWND GetProcessWindow(DWORD processId)
{

	HWND hWnd = FindWindowEx(nullptr, nullptr, nullptr, nullptr);

	while (hWnd != nullptr)
	{

		if (GetParent(hWnd) == nullptr && GetWindowTextLength(hWnd) > 0 && IsWindowVisible(hWnd))
		{

			DWORD windowProcessId;
			GetWindowThreadProcessId(hWnd, &windowProcessId);

			if (windowProcessId == processId)
			{
				// Found a match.
				break;
			}

		}

		hWnd = GetWindow(hWnd, GW_HWNDNEXT);

	}

	return hWnd;

}

void SaveIcon(HICON hIcon, const char* path) {
	unsigned int cx = GetSystemMetrics(SM_CXICON), cy = GetSystemMetrics(SM_CYICON);
	HDC hScreenDC = ::GetDC(nullptr);
	HDC hMemDC = CreateCompatibleDC(hScreenDC);
	HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, cx, cy);
	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

	//BitBlt(hMemDC, 0, 0, cx, cy, hScreenDC, 0, 0, SRCCOPY);
	DrawIcon(hMemDC, 0, 0, hIcon);

	SelectObject(hMemDC, hOldBitmap);
	::ReleaseDC(nullptr, hScreenDC);

	size_t headerSize = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
	BYTE* pHeader = new BYTE[headerSize];
	LPBITMAPINFO pbmi = (LPBITMAPINFO)pHeader;
	memset(pHeader, 0, headerSize);
	pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pbmi->bmiHeader.biBitCount = 0;
	if (!GetDIBits(hMemDC, hBitmap, 0, 0, nullptr, pbmi, DIB_RGB_COLORS))
		return;

	BITMAPFILEHEADER bmf;
	if (pbmi->bmiHeader.biSizeImage <= 0)
		pbmi->bmiHeader.biSizeImage = pbmi->bmiHeader.biWidth*abs(pbmi->bmiHeader.biHeight)*(pbmi->bmiHeader.biBitCount + 7) / 8;
	BYTE* pData = new BYTE[pbmi->bmiHeader.biSizeImage];
	bmf.bfType = 0x4D42; bmf.bfReserved1 = bmf.bfReserved2 = 0;
	bmf.bfSize = sizeof(BITMAPFILEHEADER) + headerSize + pbmi->bmiHeader.biSizeImage;
	bmf.bfOffBits = sizeof(BITMAPFILEHEADER) + headerSize;
	if (!GetDIBits(hMemDC, hBitmap, 0, abs(pbmi->bmiHeader.biHeight), pData, pbmi, DIB_RGB_COLORS))
	{
		delete[] pData;
		return;
	}
	FILE* hFile = fopen(path, "wb");
	fwrite(&bmf, sizeof(BITMAPFILEHEADER), 1, hFile);
	fwrite(pbmi, headerSize, 1, hFile);
	fwrite(pData, pbmi->bmiHeader.biSizeImage, 1, hFile);
	fclose(hFile);

	DeleteObject(hBitmap);
	DeleteDC(hMemDC);

	delete[] pData;
}

void GetProcesses(std::vector<Process>& processes)
{
	static char fileName[_MAX_PATH];
	static char tempPath[_MAX_PATH];
	// Get the id of this process so that we can filter it out of the list.
	DWORD currentProcessId = GetCurrentProcessId();

	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (snapshot != INVALID_HANDLE_VALUE)
	{

		PROCESSENTRY32 processEntry = { 0 };
		processEntry.dwSize = sizeof(processEntry);

		if (Process32First(snapshot, &processEntry))
		{
			do
			{
				if (processEntry.th32ProcessID != currentProcessId && processEntry.th32ProcessID != 0)
				{

					Process process;

					process.id = processEntry.th32ProcessID;
					process.name = processEntry.szExeFile;

					HANDLE m_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processEntry.th32ProcessID);
					if (m_process) {
						int err = GetModuleFileNameEx(m_process, nullptr, fileName, _MAX_PATH);
						if (err == 0) // ERROR_ACCESS_DENIED = 5
							process.path = "error";
						else process.path = fileName;

						if (!process.path.empty()) {
							char windowsPath[MAX_PATH];
							if (SHGetFolderPath(nullptr, CSIDL_WINDOWS, nullptr, SHGFP_TYPE_CURRENT, windowsPath) == 0) {
								if (process.path.find(windowsPath) == std::string::npos) {

									HWND hWnd = GetProcessWindow(processEntry.th32ProcessID);

									if (hWnd != nullptr)
									{
										char buffer[1024];
										GetWindowText(hWnd, buffer, 1024);
										process.title = buffer;
									}
									processes.push_back(process);
									/*SHFILEINFO info;
									SHGetFileInfo(fileName, 0, &info, sizeof(info), SHGFI_ICON | SHGFI_LARGEICON);
									if (info.hIcon) {
										GetTempPath(MAX_PATH, tempPath);
										sprintf(fileName, "%s%d.bmp", tempPath, process.id);
										process.iconPath = fileName;
										SaveIcon(info.hIcon, process.iconPath.c_str());
									}*/
								}
							}
						}
					}
				}
			} while (Process32Next(snapshot, &processEntry));

		}

		CloseHandle(snapshot);

	}

}<commit_msg>clean code<commit_after>#include "WindowUtility.h"
#include <tlhelp32.h>
#include <psapi.h>
#include <shlobj.h>

HWND GetProcessWindow(DWORD processId)
{

	HWND hWnd = FindWindowEx(nullptr, nullptr, nullptr, nullptr);

	while (hWnd != nullptr)
	{

		if (GetParent(hWnd) == nullptr && GetWindowTextLength(hWnd) > 0 && IsWindowVisible(hWnd))
		{

			DWORD windowProcessId;
			GetWindowThreadProcessId(hWnd, &windowProcessId);

			if (windowProcessId == processId)
			{
				// Found a match.
				break;
			}

		}

		hWnd = GetWindow(hWnd, GW_HWNDNEXT);

	}

	return hWnd;

}

void GetProcesses(std::vector<Process>& processes)
{
	static char fileName[_MAX_PATH];
	static char tempPath[_MAX_PATH];
	// Get the id of this process so that we can filter it out of the list.
	DWORD currentProcessId = GetCurrentProcessId();

	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (snapshot != INVALID_HANDLE_VALUE)
	{

		PROCESSENTRY32 processEntry = { 0 };
		processEntry.dwSize = sizeof(processEntry);

		if (Process32First(snapshot, &processEntry))
		{
			do
			{
				if (processEntry.th32ProcessID != currentProcessId && processEntry.th32ProcessID != 0)
				{

					Process process;

					process.id = processEntry.th32ProcessID;
					process.name = processEntry.szExeFile;

					HANDLE m_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processEntry.th32ProcessID);
					if (m_process) {
						int err = GetModuleFileNameEx(m_process, nullptr, fileName, _MAX_PATH);
						if (err == 0) // ERROR_ACCESS_DENIED = 5
							process.path = "error";
						else process.path = fileName;

						if (!process.path.empty()) {
							char windowsPath[MAX_PATH];
							if (SHGetFolderPath(nullptr, CSIDL_WINDOWS, nullptr, SHGFP_TYPE_CURRENT, windowsPath) == 0) {
								if (process.path.find(windowsPath) == std::string::npos) {

									HWND hWnd = GetProcessWindow(processEntry.th32ProcessID);

									if (hWnd != nullptr)
									{
										char buffer[1024];
										GetWindowText(hWnd, buffer, 1024);
										process.title = buffer;
									}
									processes.push_back(process);
								}
							}
						}
					}
				}
			} while (Process32Next(snapshot, &processEntry));

		}

		CloseHandle(snapshot);

	}

}<|endoftext|>


<commit_before>#include "book.hpp"

#include <algorithm>

namespace smatch {

Order& Book::insert(const Order& o)
{
    // BuySell is what we store in ids_, to allow us to quickly find orders by id
    const auto it = ids_.emplace(
        o.id , BuySell { buys_.end() , sells_.end() }
    );

    // Enforce that ids are unique
    if (not it.second)
        throw bad_order_id("Duplicate order id", o.id);

    // A shortcut for storing buy or sell iterator into BuySell we just inserted into ids_
    auto& os = it.first->second;

    // Build Priority for price and priority of the order. Since on each insert
    // we bump serial_, each such constructed Priority will be unique.
    const Priority pp { o.price , ++serial_ };

    // Store an order (limit or iceberg) in an appropriate collection buys_ or sells_
    // and persist the iterator for this element in BuySell created above.
    if (o.side == Side::Buy) {
        os.buy = buys_.emplace(pp, o).first;
        return os.buy->second;
    }
    else {
        os.sell = sells_.emplace(pp, o).first;
        return os.sell->second;
    }
}

void Book::remove(uint id)
{
    const auto i = ids_.find(id);
    if (i == ids_.end())
        throw bad_order_id("Invalid order id", id);

    if (i->second.buy != buys_.end())
        buys_.erase(i->second.buy);
    else // if (i->second.sell != sells_.end() )
        sells_.erase(i->second.sell);

    ids_.erase(i);
}

template <Side side>
void Book::match(Order& active, std::vector<Match>& matches)
{
    // Special value for active.match, set at the bottom of this function. "0" is not good because
    // the purpose of active.match is to identify Match for matched order in matches vector, and of course
    // first match added to this collection will have index 0
    constexpr auto unmatched = std::numeric_limits<size_t>::max();

    // Active order is on "this side" and it will be matched against orders on the "opposite side"
    constexpr auto opposite = (side == Side::Buy ? Side::Sell : Side::Buy);
    auto& orders = this->orders<opposite>();
    size_t count = 0; // Partially matched orders
    while (active.size > 0 && not orders.empty())
    {
        auto& top = orders.begin()->second;
        if (side == Side::Buy && active.price < top.price)
            break;
        else if (side == Side::Sell && active.price > top.price)
            break;

        const uint size = std::min(active.size, top.size);
        if (top.match == unmatched)
        {
            ++count;
            Match match;
            match.price = top.price;
            match.size = 0; // Increased below
            match.buyId = (side == Side::Buy ? active.id : top.id);
            match.sellId = (side == Side::Sell ? active.id : top.id);
            top.match = matches.size();
            matches.push_back(match);
        }
        matches[top.match].size += size;

        // Remove liquidity from active order, reset size if it is an iceberg
        active.full -= size;
        active.size = std::min(active.full, active.peak);

        // Remove liquidity from top order
        top.size -= size;
        top.full -= size;

        // This section could be slightly optimized by replacing calls to remove() and insert()
        // with custom tailored modifications of both ids_ and orders collections
        if (top.size == 0)
        {
            const Order copy = top;
            remove(copy.id);
            // Must not use top below this point
            if (copy.full > 0)
            {
                auto& renew = insert(copy);
                renew.size = std::min(copy.full, copy.peak);
            }
            else
                --count;
        }
    }

    // Clear partial matches collected so far
    size_t i = 0;
    for (auto& o : orders)
    {
        if (o.second.match == unmatched)
            continue;
        o.second.match = unmatched;
        if (++i == count)
            break;
    }
    active.match = unmatched;
}

// Explicit instantiations of the above, for Engine::handle() to use
template void Book::match<Side::Buy>(Order&, std::vector<Match>& );
template void Book::match<Side::Sell>(Order&, std::vector<Match>& );

}
<commit_msg>set unamatched special value in Book::insert() rather than in Book::match()<commit_after>#include "book.hpp"

#include <algorithm>

namespace smatch {

namespace {
    // Special value for Order.match, set at the end of Book::insert(). 0 is not good because the
    // purpose of Order.match is to identify index of Match in vector passed to Book::match(), and
    // of course first match added to this collection will have index 0
    static constexpr size_t unmatched = std::numeric_limits<size_t>::max();
}

Order& Book::insert(const Order& o)
{
    // BuySell is what we store in ids_, to allow us to quickly find orders by id
    const auto it = ids_.emplace(
        o.id , BuySell { buys_.end() , sells_.end() }
    );

    // Enforce that ids are unique
    if (not it.second)
        throw bad_order_id("Duplicate order id", o.id);

    // A shortcut for storing buy or sell iterator into BuySell we just inserted into ids_
    auto& os = it.first->second;

    // Build Priority for price and priority of the order. Since on each insert
    // we bump serial_, each such constructed Priority will be unique.
    const Priority pp { o.price , ++serial_ };

    // Store an order (limit or iceberg) in an appropriate collection buys_ or sells_
    // and persist the iterator for this element in BuySell created above.
    Order* ret = nullptr;
    if (o.side == Side::Buy) {
        os.buy = buys_.emplace(pp, o).first;
        ret = &os.buy->second;
    }
    else {
        os.sell = sells_.emplace(pp, o).first;
        ret = &os.sell->second;
    }
    ret->match = unmatched;
    return *ret;
}

void Book::remove(uint id)
{
    const auto i = ids_.find(id);
    if (i == ids_.end())
        throw bad_order_id("Invalid order id", id);

    if (i->second.buy != buys_.end())
        buys_.erase(i->second.buy);
    else // if (i->second.sell != sells_.end() )
        sells_.erase(i->second.sell);

    ids_.erase(i);
}

template <Side side>
void Book::match(Order& active, std::vector<Match>& matches)
{
    // Active order is on "this side" and it will be matched against orders on the "opposite side"
    constexpr auto opposite = (side == Side::Buy ? Side::Sell : Side::Buy);
    auto& orders = this->orders<opposite>();
    size_t count = 0; // Partially matched orders
    while (active.size > 0 && not orders.empty())
    {
        auto& top = orders.begin()->second;
        if (side == Side::Buy && active.price < top.price)
            break;
        else if (side == Side::Sell && active.price > top.price)
            break;

        const uint size = std::min(active.size, top.size);
        if (top.match == unmatched)
        {
            ++count;
            Match match;
            match.price = top.price;
            match.size = 0; // Increased below
            match.buyId = (side == Side::Buy ? active.id : top.id);
            match.sellId = (side == Side::Sell ? active.id : top.id);
            top.match = matches.size();
            matches.push_back(match);
        }
        matches[top.match].size += size;

        // Remove liquidity from active order, reset size if it is an iceberg
        active.full -= size;
        active.size = std::min(active.full, active.peak);

        // Remove liquidity from top order
        top.size -= size;
        top.full -= size;

        // This section could be slightly optimized by replacing calls to remove() and insert()
        // with custom tailored modifications of both ids_ and orders collections
        if (top.size == 0)
        {
            const Order copy = top;
            remove(copy.id);
            // Must not use top below this point
            if (copy.full > 0)
            {
                auto& renew = insert(copy);
                renew.match = copy.match;
                renew.size = std::min(copy.full, copy.peak);
            }
            else
                --count;
        }
    }

    // Clear partial matches collected so far
    size_t i = 0;
    for (auto& o : orders)
    {
        if (o.second.match == unmatched)
            continue;
        o.second.match = unmatched;
        if (++i == count)
            break;
    }
}

// Explicit instantiations of the above, for Engine::handle() to use
template void Book::match<Side::Buy>(Order&, std::vector<Match>& );
template void Book::match<Side::Sell>(Order&, std::vector<Match>& );

}
<|endoftext|>