<commit_before>//
// Created by lz on 1/25/17.
//

#include <catch.hpp>
#include <c10k/worker_thread.hpp>
#include <c10k/utils.hpp>
#include <c10k/handler.hpp>
#include "test_common.hpp"
#include <cstdint>
#include <sstream>
#include <iostream>

struct ServerHandler: public c10k::Handler
{
    std::uint16_t len;
    std::vector<char> buffer;
    virtual void handle_init(const c10k::ConnectionPtr &conn) override
    {
        using namespace std::placeholders;
        using std::static_pointer_cast;
        C10K_READ_ASYNC_THEN_MEMFUN(conn, (char*)&len, sizeof(len), read_buffer);
    }

    void read_buffer(const c10k::ConnectionPtr &conn, char *st, char *ed)
    {
        using namespace std::placeholders;
        buffer.reserve(len);
        C10K_READ_ASYNC_THEN_MEMFUN(conn, std::back_inserter(buffer), len, write_back);
    }

    void write_back(const c10k::ConnectionPtr &conn, char *st, char *ed) {
        using namespace std::placeholders;
        std::vector<char> wrt_buffer;
        wrt_buffer.reserve(2 + len);
        std::copy_n((char *) &len, 2, std::back_inserter(wrt_buffer));
        std::copy(buffer.begin(), buffer.end(), std::back_inserter(wrt_buffer));
        C10K_WRITE_ASYNC_THEN_MEMFUN(conn, wrt_buffer.begin(), wrt_buffer.end(), close_connection);
    }

    void close_connection(const c10k::ConnectionPtr &conn)
    {
        conn->close();
    }
};

std::atomic_bool check_ok {true};
std::stringstream ss;

struct ClientHandler: public c10k::Handler
{
    std::vector<char> gen_data()
    {
        std::vector<char> wrt_buffer;
        std::uint16_t len = std::rand() % 32768;
        wrt_buffer.reserve(2 + len);
        std::copy_n((char *)&len, 2, std::back_inserter(wrt_buffer));
        std::generate_n(std::back_inserter(wrt_buffer), len, []() {
            return std::rand() % 128;;
        });
        return wrt_buffer;
    }

    std::vector<char> send_data, recv_data;
    virtual void handle_init(const c10k::ConnectionPtr &conn) override
    {
        using namespace std::placeholders;
        send_data = gen_data();
        conn->write_async(send_data.cbegin(), send_data.cend());
        conn->read_async_then(std::back_inserter(recv_data), send_data.size(),
            std::bind(&ClientHandler::check_data,
                      std::static_pointer_cast<ClientHandler>(shared_from_this()), _1, _2, _3));
    }

    void check_data(const c10k::ConnectionPtr &conn, char *st, char *ed)
    {
        bool ok = true;
        ok &= send_data.size() == recv_data.size();
        if (ok)
            for (int i=0; i<send_data.size(); ++i) {
                ok &= send_data[i] == recv_data[i];
                if (send_data[i] != recv_data[i]) {
                    for (int j=i-5; j < i+5 && j<send_data.size(); ++j)
                        ss << "Pos[" << j << "]: send=" << send_data[j] << " recv=" << recv_data[j] << std::endl;
                    ss << "At pos " << i << " send=" << (int) send_data[i] << " recv=" << (int) recv_data[i] <<
                                   " size=" << recv_data.size() <<
                                   " fd=" << conn->getFD() << std::endl;
                }
            }
        if (check_ok.load() && !ok) {
            check_ok = ok;
            ss << "Err!" << "Send size="<< send_data.size() <<" recv size=" << recv_data.size() << std::endl;
        }
        conn->close();
    }
};

TEST_CASE("multiple WorkerThread test", "[worker_thread]")
{
    using namespace std::chrono_literals;
    using namespace c10k;
    using detail::call_must_ok;
    spdlog::set_level(spdlog::level::debug);
    auto server_logger = spdlog::stdout_color_mt("Server"), client_logger = spdlog::stdout_color_mt("Client"),
        debug_logger = spdlog::stdout_color_mt("DEBUG");
    detail::WorkerThread<ServerHandler> worker(400, server_logger);

    std::thread server_t {std::ref(worker)};
    server_t.detach();
    static constexpr int TEST_CNT = 500;

    std::thread main_t {[&]() {
        int main_fd = create_socket();
        sockaddr_in addr = create_addr("127.0.0.1", 6503);
        call_must_ok(::bind, "Bind", main_fd, (sockaddr*)&addr, sizeof(addr));
        call_must_ok(::listen, "Listen", main_fd, 1024);
        for (int i=0; i<TEST_CNT; ++i)
        {
            int new_sock = call_must_ok(accept, "Accept", main_fd, nullptr, nullptr);
            make_socket_nonblocking(new_sock);
            server_logger->info("new fd created = {}", new_sock);
            worker.add_new_connection(new_sock);
        }
        call_must_ok(::close, "close", main_fd);
    }};
    main_t.detach();
    debug_logger->info("Main thread detached");
    cur_sleep_for(3s);
    debug_logger->info("Start to create clientWorker");

    detail::WorkerThread<ClientHandler> clientWorker(400, client_logger);
    std::thread client_t {std::ref(clientWorker)};
    client_t.detach();
    debug_logger->info("ClientWorker created");

    for (int i=0; i<TEST_CNT; ++i)
    {
        int cli_fd = create_socket(true);
        sockaddr_in addr = create_addr("127.0.0.1", 6503);
        call_must_ok(::connect, "Connect", cli_fd, (sockaddr*)&addr, sizeof(addr));
        debug_logger->info("New fd added {}: {}/{}", cli_fd, i, TEST_CNT);
        make_socket_nonblocking(cli_fd);
        clientWorker.add_new_connection(cli_fd);
    }

    cur_sleep_for(25s);
    worker.stop(); clientWorker.stop();
    cur_sleep_for(3s);
    INFO(ss.str());
    REQUIRE(check_ok);
}<commit_msg>Test: WorkerThread: Use union to alias len<commit_after>//
// Created by lz on 1/25/17.
//

#include <catch.hpp>
#include <c10k/worker_thread.hpp>
#include <c10k/utils.hpp>
#include <c10k/handler.hpp>
#include "test_common.hpp"
#include <cstdint>
#include <sstream>
#include <iostream>

struct ServerHandler: public c10k::Handler
{
    union {
        std::uint16_t len_int;
        char len_chars[2];
    } len;
    std::vector<char> buffer;
    virtual void handle_init(const c10k::ConnectionPtr &conn) override
    {
        using namespace std::placeholders;
        using std::static_pointer_cast;
        C10K_READ_ASYNC_THEN_MEMFUN(conn, len.len_chars, 2, read_buffer);
    }

    void read_buffer(const c10k::ConnectionPtr &conn, char *st, char *ed)
    {
        using namespace std::placeholders;
        buffer.reserve(len.len_int);
        C10K_READ_ASYNC_THEN_MEMFUN(conn, std::back_inserter(buffer), len.len_int, write_back);
    }

    void write_back(const c10k::ConnectionPtr &conn, char *st, char *ed) {
        using namespace std::placeholders;
        std::vector<char> wrt_buffer;
        wrt_buffer.reserve(2 + len.len_int);
        std::copy_n(len.len_chars, 2, std::back_inserter(wrt_buffer));
        std::copy(buffer.begin(), buffer.end(), std::back_inserter(wrt_buffer));
        C10K_WRITE_ASYNC_THEN_MEMFUN(conn, wrt_buffer.begin(), wrt_buffer.end(), close_connection);
    }

    void close_connection(const c10k::ConnectionPtr &conn)
    {
        conn->close();
    }
};

std::atomic_bool check_ok {true};
std::stringstream ss;

struct ClientHandler: public c10k::Handler
{
    union Len
    {
        std::uint16_t len_int;
        char len_chars[2];
    };
    std::vector<char> gen_data()
    {
        std::vector<char> wrt_buffer;
        Len len;
        len.len_int = std::rand() % 32768;
        wrt_buffer.reserve(2 + len.len_int);
        std::copy_n(len.len_chars, 2, std::back_inserter(wrt_buffer));
        std::generate_n(std::back_inserter(wrt_buffer), len.len_int, []() {
            return std::rand() % 128;;
        });
        return wrt_buffer;
    }

    std::vector<char> send_data, recv_data;
    virtual void handle_init(const c10k::ConnectionPtr &conn) override
    {
        using namespace std::placeholders;
        send_data = gen_data();
        conn->write_async(send_data.cbegin(), send_data.cend());
        conn->read_async_then(std::back_inserter(recv_data), send_data.size(),
            std::bind(&ClientHandler::check_data,
                      std::static_pointer_cast<ClientHandler>(shared_from_this()), _1, _2, _3));
    }

    void check_data(const c10k::ConnectionPtr &conn, char *st, char *ed)
    {
        bool ok = true;
        ok &= send_data.size() == recv_data.size();
        if (ok)
            for (int i=0; i<send_data.size(); ++i) {
                ok &= send_data[i] == recv_data[i];
                if (send_data[i] != recv_data[i]) {
                    for (int j=i-5; j < i+5 && j<send_data.size(); ++j)
                        ss << "Pos[" << j << "]: send=" << send_data[j] << " recv=" << recv_data[j] << std::endl;
                    ss << "At pos " << i << " send=" << (int) send_data[i] << " recv=" << (int) recv_data[i] <<
                                   " size=" << recv_data.size() <<
                                   " fd=" << conn->getFD() << std::endl;
                }
            }
        if (check_ok.load() && !ok) {
            check_ok = ok;
            ss << "Err!" << "Send size="<< send_data.size() <<" recv size=" << recv_data.size() << std::endl;
        }
        conn->close();
    }
};

TEST_CASE("multiple WorkerThread test", "[worker_thread]")
{
    using namespace std::chrono_literals;
    using namespace c10k;
    using detail::call_must_ok;
    spdlog::set_level(spdlog::level::debug);
    auto server_logger = spdlog::stdout_color_mt("Server"), client_logger = spdlog::stdout_color_mt("Client"),
        debug_logger = spdlog::stdout_color_mt("DEBUG");
    detail::WorkerThread<ServerHandler> worker(400, server_logger);

    std::thread server_t {std::ref(worker)};
    server_t.detach();
    static constexpr int TEST_CNT = 500;

    std::thread main_t {[&]() {
        int main_fd = create_socket();
        sockaddr_in addr = create_addr("127.0.0.1", 6503);
        call_must_ok(::bind, "Bind", main_fd, (sockaddr*)&addr, sizeof(addr));
        call_must_ok(::listen, "Listen", main_fd, 1024);
        for (int i=0; i<TEST_CNT; ++i)
        {
            int new_sock = call_must_ok(accept, "Accept", main_fd, nullptr, nullptr);
            make_socket_nonblocking(new_sock);
            server_logger->info("new fd created = {}", new_sock);
            worker.add_new_connection(new_sock);
        }
        call_must_ok(::close, "close", main_fd);
    }};
    main_t.detach();
    debug_logger->info("Main thread detached");
    cur_sleep_for(3s);
    debug_logger->info("Start to create clientWorker");

    detail::WorkerThread<ClientHandler> clientWorker(400, client_logger);
    std::thread client_t {std::ref(clientWorker)};
    client_t.detach();
    debug_logger->info("ClientWorker created");

    for (int i=0; i<TEST_CNT; ++i)
    {
        int cli_fd = create_socket(true);
        sockaddr_in addr = create_addr("127.0.0.1", 6503);
        call_must_ok(::connect, "Connect", cli_fd, (sockaddr*)&addr, sizeof(addr));
        debug_logger->info("New fd added {}: {}/{}", cli_fd, i, TEST_CNT);
        make_socket_nonblocking(cli_fd);
        clientWorker.add_new_connection(cli_fd);
    }

    cur_sleep_for(25s);
    worker.stop(); clientWorker.stop();
    cur_sleep_for(3s);
    INFO(ss.str());
    REQUIRE(check_ok);
}<|endoftext|>


<commit_before><commit_msg>Let's see if stripping the const here will fix the clang build...<commit_after><|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "DocumentDBServlet.h"
#include "stx/human.h"

using namespace stx;

namespace zbase {

DocumentDBServlet::DocumentDBServlet(
    DocumentDB* docdb) :
    docdb_(docdb) {}

void DocumentDBServlet::handle(
    const AnalyticsSession& session,
    const stx::http::HTTPRequest* req,
    stx::http::HTTPResponse* res) {
  static const String kPathPrefix = "/api/v1/documents";
  URI uri(req->uri());

  // LIST
  if (req->method() == http::HTTPMessage::M_GET &&
      uri.path() == kPathPrefix) {
    listDocuments(session, req, res);
    return;
  }

  // GET
  if (req->method() == http::HTTPMessage::M_GET &&
      StringUtil::beginsWith(uri.path(), kPathPrefix)) {
    auto docid = SHA1Hash::fromHexString(
        uri.path().substr(kPathPrefix.size() + 1));

    fetchDocument(docid, uri, session, req, res);
    return;
  }

  // CREATE
  if (req->method() == http::HTTPMessage::M_POST &&
      uri.path() == kPathPrefix) {
    createDocument(uri, session, req, res);
    return;
  }

  // UPDATE
  if (req->method() == http::HTTPMessage::M_POST &&
      StringUtil::beginsWith(uri.path(), kPathPrefix)) {
    auto docid = SHA1Hash::fromHexString(
        uri.path().substr(kPathPrefix.size() + 1));

    updateDocument(docid, uri, session, req, res);
    return;
  }

  res->setStatus(stx::http::kStatusNotFound);
  res->addBody("not found");
}

void DocumentDBServlet::fetchDocument(
    const SHA1Hash& uuid,
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  const auto& params = uri.queryParams();

  bool return_content = true;
  String no_content_str;
  if (URI::getParam(params, "no_content", &no_content_str)) {
    return_content = false;
  }

  Document doc;
  if (docdb_->fetchDocument(session.customer(), session.userid(), uuid, &doc)) {
    Buffer buf;
    json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));
    renderDocument(session, doc, &json, return_content);
    res->setStatus(http::kStatusOK);
    res->addBody(buf);
  } else {
    res->setStatus(http::kStatusNotFound);
    res->addBody("not found");
  }
}

void DocumentDBServlet::createDocument(
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI::ParamList params;
  URI::parseQueryString(req->body().toString(), &params);

  String name;
  if (!URI::getParam(params, "name", &name)) {
    res->setStatus(http::kStatusBadRequest);
    res->addBody("missing ?name=... parameter");
  }

  String type;
  if (!URI::getParam(params, "type", &type)) {
    res->setStatus(http::kStatusBadRequest);
    res->addBody("missing ?type=... parameter");
  }

  auto now = WallClock::unixMicros();

  Document doc;
  doc.set_uuid(Random::singleton()->sha1().toString());
  doc.set_name(name);
  doc.set_type(type);
  doc.set_version(0);
  doc.set_ctime(now);
  doc.set_mtime(now);
  doc.set_atime(now);

  setDefaultDocumentACLs(&doc, session.userid());

  docdb_->createDocument(session.customer(), doc);

  Buffer buf;
  json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));
  renderDocument(session, doc, &json);
  res->setStatus(http::kStatusCreated);
  res->addBody(buf);
}

void DocumentDBServlet::updateDocument(
    const SHA1Hash& uuid,
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI::ParamList params;
  URI::parseQueryString(req->body().toString(), &params);

  Vector<Function<void ()>> tx;

  for (const auto& p : params) {

    if (p.first == "content") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentContent(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "name") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentName(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "category") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentCategory(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "acl_policy") {
      if (!p.second.empty()) {
        DocumentACLPolicy policy;
        if (!DocumentACLPolicy_Parse(p.second, &policy)) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(StringUtil::format("invalid policy: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, policy] () {
          docdb_->updateDocumentACLPolicy(
              session.customer(),
              session.userid(),
              uuid,
              policy);
        });
      }

      continue;
    }

    if (p.first == "publishing_status") {
      if (!p.second.empty()) {
        DocumentPublishingStatus pstatus;
        if (!DocumentPublishingStatus_Parse(p.second, &pstatus)) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(
              StringUtil::format("invalid publishing status: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, pstatus] () {
          docdb_->updateDocumentPublishingStatus(
              session.customer(),
              session.userid(),
              uuid,
              pstatus);
        });
      }

      continue;
    }

    if (p.first == "deleted") {
      if (!p.second.empty()) {
        auto deleted = Human::parseBoolean(p.second);
        if (deleted.isEmpty()) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(
              StringUtil::format("invalid deleted status: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, deleted] () {
          docdb_->updateDocumentDeletedStatus(
              session.customer(),
              session.userid(),
              uuid,
              deleted.get());
        });
      }

      continue;
    }

    res->setStatus(http::kStatusBadRequest);
    res->addBody(StringUtil::format("invalid parameter: '$0'", p.first));
    return;
  }

  for (const auto& fn : tx) {
    fn();
  }

  res->setStatus(http::kStatusCreated);
}

void DocumentDBServlet::listDocuments(
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI uri(req->uri());
  const auto& params = uri.queryParams();

  Set<String> categories;
  bool return_categories = false;
  String with_categories_str;
  if (URI::getParam(params, "with_categories", &with_categories_str)) {
    return_categories = true;
  }

  Buffer buf;
  json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));

  json.beginObject();
  json.addObjectEntry("documents");
  json.beginArray();

  size_t i = 0;
  docdb_->listDocuments(
      session.customer(),
      session.userid(),
      [this, &i, &json, &session, &categories] (const Document& doc) -> bool {
    if (!doc.category().empty()) {
      categories.emplace(doc.category());
    }

    if (++i > 1) {
      json.addComma();
    }

    renderDocument(
        session,
        doc,
        &json,
        false);

    return true;
  });

  json.endArray();

  if (return_categories) {
    json.addComma();
    json.addObjectEntry("categories");
    json::toJSON(categories, &json);
  }

  json.endObject();

  res->setStatus(http::kStatusOK);
  res->setHeader("Content-Type", "application/json; charset=utf-8");
  res->addBody(buf);
}

void DocumentDBServlet::renderDocument(
    const AnalyticsSession& session,
    const Document& doc,
    json::JSONOutputStream* json,
    bool return_content /* = true */) {
  json->beginObject();

  json->addObjectEntry("uuid");
  json->addString(doc.uuid());
  json->addComma();

  json->addObjectEntry("name");
  json->addString(doc.name());
  json->addComma();

  json->addObjectEntry("type");
  json->addString(doc.type());
  json->addComma();

  json->addObjectEntry("publishing_status");
  json->addString(DocumentPublishingStatus_Name(doc.publishing_status()));
  json->addComma();

  json->addObjectEntry("category");
  json->addString(doc.category());
  json->addComma();

  json->addObjectEntry("acl_policy");
  json->addString(DocumentACLPolicy_Name(doc.acl_policy()));
  json->addComma();

  json->addObjectEntry("is_readable");
  json->addBool(isDocumentReadableForUser(doc, session.userid()));
  json->addComma();

  json->addObjectEntry("is_writable");
  json->addBool(isDocumentWritableForUser(doc, session.userid()));
  json->addComma();

  json->addObjectEntry("deleted");
  json->addBool(doc.deleted());
  json->addComma();

  json->addObjectEntry("ctime");
  json->addInteger(doc.ctime());
  json->addComma();

  json->addObjectEntry("mtime");
  json->addInteger(doc.mtime());
  json->addComma();

  json->addObjectEntry("atime");
  json->addInteger(doc.atime());

  if (return_content) {
    json->addComma();
    json->addObjectEntry("content");
    json->addString(doc.content());
  }

  json->endObject();
}

} // namespace zbase
<commit_msg>publishing status filter<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "DocumentDBServlet.h"
#include "stx/human.h"

using namespace stx;

namespace zbase {

DocumentDBServlet::DocumentDBServlet(
    DocumentDB* docdb) :
    docdb_(docdb) {}

void DocumentDBServlet::handle(
    const AnalyticsSession& session,
    const stx::http::HTTPRequest* req,
    stx::http::HTTPResponse* res) {
  static const String kPathPrefix = "/api/v1/documents";
  URI uri(req->uri());

  // LIST
  if (req->method() == http::HTTPMessage::M_GET &&
      uri.path() == kPathPrefix) {
    listDocuments(session, req, res);
    return;
  }

  // GET
  if (req->method() == http::HTTPMessage::M_GET &&
      StringUtil::beginsWith(uri.path(), kPathPrefix)) {
    auto docid = SHA1Hash::fromHexString(
        uri.path().substr(kPathPrefix.size() + 1));

    fetchDocument(docid, uri, session, req, res);
    return;
  }

  // CREATE
  if (req->method() == http::HTTPMessage::M_POST &&
      uri.path() == kPathPrefix) {
    createDocument(uri, session, req, res);
    return;
  }

  // UPDATE
  if (req->method() == http::HTTPMessage::M_POST &&
      StringUtil::beginsWith(uri.path(), kPathPrefix)) {
    auto docid = SHA1Hash::fromHexString(
        uri.path().substr(kPathPrefix.size() + 1));

    updateDocument(docid, uri, session, req, res);
    return;
  }

  res->setStatus(stx::http::kStatusNotFound);
  res->addBody("not found");
}

void DocumentDBServlet::fetchDocument(
    const SHA1Hash& uuid,
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  const auto& params = uri.queryParams();

  bool return_content = true;
  String no_content_str;
  if (URI::getParam(params, "no_content", &no_content_str)) {
    return_content = false;
  }

  Document doc;
  if (docdb_->fetchDocument(session.customer(), session.userid(), uuid, &doc)) {
    Buffer buf;
    json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));
    renderDocument(session, doc, &json, return_content);
    res->setStatus(http::kStatusOK);
    res->addBody(buf);
  } else {
    res->setStatus(http::kStatusNotFound);
    res->addBody("not found");
  }
}

void DocumentDBServlet::createDocument(
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI::ParamList params;
  URI::parseQueryString(req->body().toString(), &params);

  String name;
  if (!URI::getParam(params, "name", &name)) {
    res->setStatus(http::kStatusBadRequest);
    res->addBody("missing ?name=... parameter");
  }

  String type;
  if (!URI::getParam(params, "type", &type)) {
    res->setStatus(http::kStatusBadRequest);
    res->addBody("missing ?type=... parameter");
  }

  auto now = WallClock::unixMicros();

  Document doc;
  doc.set_uuid(Random::singleton()->sha1().toString());
  doc.set_name(name);
  doc.set_type(type);
  doc.set_version(0);
  doc.set_ctime(now);
  doc.set_mtime(now);
  doc.set_atime(now);

  setDefaultDocumentACLs(&doc, session.userid());

  docdb_->createDocument(session.customer(), doc);

  Buffer buf;
  json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));
  renderDocument(session, doc, &json);
  res->setStatus(http::kStatusCreated);
  res->addBody(buf);
}

void DocumentDBServlet::updateDocument(
    const SHA1Hash& uuid,
    const URI& uri,
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI::ParamList params;
  URI::parseQueryString(req->body().toString(), &params);

  Vector<Function<void ()>> tx;

  for (const auto& p : params) {

    if (p.first == "content") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentContent(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "name") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentName(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "category") {
      if (!p.second.empty()) {
        tx.emplace_back([this, &session, &uuid, p] () {
          docdb_->updateDocumentCategory(
              session.customer(),
              session.userid(),
              uuid,
              p.second);
        });
      }

      continue;
    }

    if (p.first == "acl_policy") {
      if (!p.second.empty()) {
        DocumentACLPolicy policy;
        if (!DocumentACLPolicy_Parse(p.second, &policy)) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(StringUtil::format("invalid policy: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, policy] () {
          docdb_->updateDocumentACLPolicy(
              session.customer(),
              session.userid(),
              uuid,
              policy);
        });
      }

      continue;
    }

    if (p.first == "publishing_status") {
      if (!p.second.empty()) {
        DocumentPublishingStatus pstatus;
        if (!DocumentPublishingStatus_Parse(p.second, &pstatus)) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(
              StringUtil::format("invalid publishing status: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, pstatus] () {
          docdb_->updateDocumentPublishingStatus(
              session.customer(),
              session.userid(),
              uuid,
              pstatus);
        });
      }

      continue;
    }

    if (p.first == "deleted") {
      if (!p.second.empty()) {
        auto deleted = Human::parseBoolean(p.second);
        if (deleted.isEmpty()) {
          res->setStatus(http::kStatusBadRequest);
          res->addBody(
              StringUtil::format("invalid deleted status: '$0'", p.second));
          return;
        }

        tx.emplace_back([this, &session, &uuid, deleted] () {
          docdb_->updateDocumentDeletedStatus(
              session.customer(),
              session.userid(),
              uuid,
              deleted.get());
        });
      }

      continue;
    }

    res->setStatus(http::kStatusBadRequest);
    res->addBody(StringUtil::format("invalid parameter: '$0'", p.first));
    return;
  }

  for (const auto& fn : tx) {
    fn();
  }

  res->setStatus(http::kStatusCreated);
}

void DocumentDBServlet::listDocuments(
    const AnalyticsSession& session,
    const http::HTTPRequest* req,
    http::HTTPResponse* res) {
  URI uri(req->uri());
  const auto& params = uri.queryParams();

  /* param: with_categories */
  Set<String> categories;
  bool return_categories = false;
  String with_categories_str;
  if (URI::getParam(params, "with_categories", &with_categories_str)) {
    return_categories = true;
  }

  /* param: publishing_status */
  Option<DocumentPublishingStatus> pstatus_filter;
  String pstatus_filter_str;
  if (URI::getParam(params, "publishing_status", &pstatus_filter_str)) {
    DocumentPublishingStatus pstatus;
    if (!DocumentPublishingStatus_Parse(pstatus_filter_str, &pstatus)) {
      res->setStatus(http::kStatusBadRequest);
      res->addBody(StringUtil::format(
          "invalid publishing status: '$0'",
          pstatus_filter_str));
      return;
    }

    pstatus_filter = Some(pstatus);
  }

  /* scan documents */
  Buffer buf;
  json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));

  json.beginObject();
  json.addObjectEntry("documents");
  json.beginArray();

  size_t i = 0;
  docdb_->listDocuments(
      session.customer(),
      session.userid(),
      [&] (const Document& doc) -> bool {
    if (!doc.category().empty()) {
      categories.emplace(doc.category());
    }

    if (!pstatus_filter.isEmpty() &&
        doc.publishing_status() != pstatus_filter.get()) {
      return true;
    }

    if (++i > 1) {
      json.addComma();
    }

    renderDocument(
        session,
        doc,
        &json,
        false);

    return true;
  });

  json.endArray();

  if (return_categories) {
    json.addComma();
    json.addObjectEntry("categories");
    json::toJSON(categories, &json);
  }

  json.endObject();

  res->setStatus(http::kStatusOK);
  res->setHeader("Content-Type", "application/json; charset=utf-8");
  res->addBody(buf);
}

void DocumentDBServlet::renderDocument(
    const AnalyticsSession& session,
    const Document& doc,
    json::JSONOutputStream* json,
    bool return_content /* = true */) {
  json->beginObject();

  json->addObjectEntry("uuid");
  json->addString(doc.uuid());
  json->addComma();

  json->addObjectEntry("name");
  json->addString(doc.name());
  json->addComma();

  json->addObjectEntry("type");
  json->addString(doc.type());
  json->addComma();

  json->addObjectEntry("publishing_status");
  json->addString(DocumentPublishingStatus_Name(doc.publishing_status()));
  json->addComma();

  json->addObjectEntry("category");
  json->addString(doc.category());
  json->addComma();

  json->addObjectEntry("acl_policy");
  json->addString(DocumentACLPolicy_Name(doc.acl_policy()));
  json->addComma();

  json->addObjectEntry("is_readable");
  json->addBool(isDocumentReadableForUser(doc, session.userid()));
  json->addComma();

  json->addObjectEntry("is_writable");
  json->addBool(isDocumentWritableForUser(doc, session.userid()));
  json->addComma();

  json->addObjectEntry("deleted");
  json->addBool(doc.deleted());
  json->addComma();

  json->addObjectEntry("ctime");
  json->addInteger(doc.ctime());
  json->addComma();

  json->addObjectEntry("mtime");
  json->addInteger(doc.mtime());
  json->addComma();

  json->addObjectEntry("atime");
  json->addInteger(doc.atime());

  if (return_content) {
    json->addComma();
    json->addObjectEntry("content");
    json->addString(doc.content());
  }

  json->endObject();
}

} // namespace zbase
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_LOG1P_EXP_HPP
#define STAN_MATH_PRIM_MAT_FUN_LOG1P_EXP_HPP

#include <stan/math/prim/mat/vectorize/apply_scalar_unary.hpp>
#include <stan/math/prim/mat/vectorize/apply_scalar_unary.hpp>

namespace stan {
  namespace math {

    /**
     * Structure to wrap log1m_exp() so that it can be vectorized.
     * @param x Variable.
     * @tparam T Variable type.
     * @return Natural log of (1 + exp(x)).
     */
    struct log1p_exp_fun {
      template <typename T>
      static inline T fun(const T& x) {
        using stan::math::log1p_exp;
        return log1p_exp(x);
      }
    };

    /**
     * Vectorized version of log1m_exp().
     * @param x Container.
     * @tparam T Container type.
     * @return Natural log of (1 + exp()) applied to each value in x.
     */
    template <typename T>
    inline typename apply_scalar_unary<log1p_exp_fun, T>::return_t
    log1p_exp(const T& x) {
      return apply_scalar_unary<log1p_exp_fun, T>::apply(x);
    }

  }
}

#endif
<commit_msg>Fixed includes<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_LOG1P_EXP_HPP
#define STAN_MATH_PRIM_MAT_FUN_LOG1P_EXP_HPP

#include <stan/math/prim/mat/vectorize/apply_scalar_unary.hpp>
#include <stan/math/prim/scal/fun/log1p_exp.hpp>

namespace stan {
  namespace math {

    /**
     * Structure to wrap log1m_exp() so that it can be vectorized.
     * @param x Variable.
     * @tparam T Variable type.
     * @return Natural log of (1 + exp(x)).
     */
    struct log1p_exp_fun {
      template <typename T>
      static inline T fun(const T& x) {
        using stan::math::log1p_exp;
        return log1p_exp(x);
      }
    };

    /**
     * Vectorized version of log1m_exp().
     * @param x Container.
     * @tparam T Container type.
     * @return Natural log of (1 + exp()) applied to each value in x.
     */
    template <typename T>
    inline typename apply_scalar_unary<log1p_exp_fun, T>::return_t
    log1p_exp(const T& x) {
      return apply_scalar_unary<log1p_exp_fun, T>::apply(x);
    }

  }
}

#endif
<|endoftext|>


<commit_before><commit_msg>planning: ignore PEDESTRIAN(s) if they are behind adc<commit_after><|endoftext|>


<commit_before>#include "../Functionalities.h"
#include <vector>
#include <string>

#include "../../Fuzzy.h"

#include "../../language/Grammar.h"

#include "../../util/Sysout.h"

bool Move::execute(gmr::SentenceState* stnc, std::vector<std::string>* argumentWords, std::string alias)
{
    if(argumentWords->size() == 0)
    {
        Sysout::println("Specify a direction.");
    }

    Fuzzy::runningGame->runCommandFromSudoInput("eat a potato");

    if(argumentWords->front() == "north")
    {
        Sysout::println("You moved north.");
    }

    if(argumentWords->front() == "west")
    {
        Sysout::println("You moved west.");
    }

    if(argumentWords->front() == "east")
    {
        Sysout::println("You moved east.");
    }

    if(argumentWords->front() == "south")
    {
        Sysout::println("You moved south.");
    }

    Sysout::println(Sysout::toFriendlyString(*Fuzzy::runningGame->player->roomLocation));

    return true;
}

<commit_msg>Made Move move<commit_after>#include "../Functionalities.h"
#include <vector>
#include <string>

#include "../../Fuzzy.h"

#include "../../language/Grammar.h"

#include "../../util/Sysout.h"

bool Move::execute(gmr::SentenceState* stnc, std::vector<std::string>* argumentWords, std::string alias)
{
    if(argumentWords->size() == 0)
    {
        Sysout::println("Specify a direction.");
    }

    Player* player = Fuzzy::runningGame->player;

    if(argumentWords->front() == "west")
    {
        Sysout::println("You moved west.");

        -- player->roomLocation->x;
    }

    if(argumentWords->front() == "east")
    {
        Sysout::println("You moved east.");

        ++ player->roomLocation->x;
    }

    if(argumentWords->front() == "south")
    {
        Sysout::println("You moved south.");

        ++ player->roomLocation->z;
    }

    if(argumentWords->front() == "north")
    {
        Sysout::println("You moved north.");

        -- player->roomLocation->z;
    }

    Sysout::d_println(Sysout::toFriendlyString(*Fuzzy::runningGame->player->roomLocation));

    return true;
}

<|endoftext|>


<commit_before>
#include "AllocationAstConsumer.h"

#include <clang/ASTMatchers/ASTMatchers.h>

using namespace clang;

namespace typegrind {
bool operator==(SpecializedInfo const& a, SpecializedInfo const& b) {
  return a.canonicalName == b.canonicalName && a.specificName == b.specificName &&
         a.uniqueId == b.uniqueId;
}

AllocationASTConsumer::AllocationASTConsumer(clang::Rewriter*& rewriter, AppConfig const& appConfig)
    : mRewriter(rewriter)
    , mAppConfig(appConfig)
    , mNewExprHandler(mRewriter, *this)
    , mOpNewExprHandler(mRewriter, *this)
    , mOpDeleteExprHandler(mRewriter, *this)
    , mDeleteExprHandler(mRewriter, *this)
    , mFunctionDeclHandler(mRewriter, *this, appConfig.getMethodMatcher())
    , mRecordDeclHandler(mRewriter, *this)

{
  using namespace ast_matchers;
  mMatcher.addMatcher(cxxNewExpr().bind("newStmt"), &mNewExprHandler);
  mMatcher.addMatcher(functionDecl().bind("decl"), &mFunctionDeclHandler);
  mMatcher.addMatcher(cxxRecordDecl().bind("decl"), &mRecordDeclHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cxxStaticCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cxxReinterpretCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cStyleCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator new")).bind("fun"))).bind("newStmt"),
      &mOpNewExprHandler);

  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cxxReinterpretCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cxxStaticCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cStyleCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun"))).bind("newStmt"),
      &mOpNewExprHandler);

  mMatcher.addMatcher(cxxDeleteExpr().bind("deleteStmt"), &mDeleteExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator delete")).bind("fun"))).bind("deleteStmt"),
      &mOpDeleteExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator delete[]")).bind("fun"))).bind("deleteStmt"),
      &mOpDeleteExprHandler);
}

void AllocationASTConsumer::HandleTranslationUnit(ASTContext& context) {
  if (mRewriter == nullptr) {
    mRewriter = new clang::Rewriter(context.getSourceManager(), context.getLangOpts());
  }
  mMatcher.matchAST(context);

  if (mAppConfig.shouldPrependInclude()) {
    auto mainFile = context.getSourceManager().getMainFileID();
    auto mainStartLocation = context.getSourceManager().getLocForStartOfFile(mainFile);
    std::string includeStmt;
    for (std::string const& inc : mAppConfig.getPrependInclude()) {
      includeStmt += "#include <" + inc + ">\n";
    }
    mRewriter->InsertText(mainStartLocation, includeStmt);
  }

  {
    auto mainFile = context.getSourceManager().getMainFileID();
    auto mainEndLocation = context.getSourceManager().getLocForEndOfFile(mainFile);
    insertSpecializedInformation(*mRewriter, mainEndLocation);
  }

  processRewriterData(mRewriter);
}

void AllocationASTConsumer::processRewriterData(clang::Rewriter*& rewriter) {
  // nop
}

void AllocationASTConsumer::handleSpecializedType(
    clang::QualType const& typeInfo, unsigned specificUniqId,
    SpecializationHandler::PointeeConversion convertToPointee /*=KEEP_ORIGINAL_TYPE*/) {
  clang::LangOptions options;
  clang::PrintingPolicy policy(options);
  policy.SuppressUnwrittenScope = true;
  policy.SuppressTagKeyword = true;

  clang::QualType st = typeInfo;
  if (convertToPointee == CONVERT_TO_POINTEE && !st->getPointeeType().isNull()) {
    st = st->getPointeeType();
  }

  clang::QualType ct = typeInfo;
  if (!ct.isCanonical()) ct = ct.getCanonicalType();
  if (convertToPointee == CONVERT_TO_POINTEE && !ct->getPointeeType().isNull()) {
    ct = ct->getPointeeType();
  }

  mCanonicalSpecializations.insert(ct.getAsString(policy));
  mSpecificSpecializations.insert(
      SpecializedInfo{ct.getAsString(policy), st.getAsString(policy), specificUniqId});
}

void AllocationASTConsumer::insertSpecializedInformation(clang::Rewriter& rewriter,
                                                         clang::SourceLocation pos) const {
  std::string str = "\n\n\n";
  for (std::string const& type : mCanonicalSpecializations) {
    str += "TYPEGRIND_CANONICAL_SPECIALIZATION(TYPEGRIND_TYPE(" + type + "));\n";
  }

  for (auto const& type : mSpecificSpecializations) {
    str += "TYPEGRIND_SPECIFIC_SPECIALIZATION(TYPEGRIND_TYPE(" + type.canonicalName +
           "), TYPEGRIND_TYPE(" + type.specificName + "), " + std::to_string(type.uniqueId) +
           ");\n";
  }

  rewriter.InsertText(pos, str);
}
}
<commit_msg>using the new prepend api<commit_after>
#include "AllocationAstConsumer.h"

#include <clang/ASTMatchers/ASTMatchers.h>

using namespace clang;

namespace typegrind {
bool operator==(SpecializedInfo const& a, SpecializedInfo const& b) {
  return a.canonicalName == b.canonicalName && a.specificName == b.specificName &&
         a.uniqueId == b.uniqueId;
}

AllocationASTConsumer::AllocationASTConsumer(clang::Rewriter*& rewriter, AppConfig const& appConfig)
    : mRewriter(rewriter)
    , mAppConfig(appConfig)
    , mNewExprHandler(mRewriter, *this)
    , mOpNewExprHandler(mRewriter, *this)
    , mOpDeleteExprHandler(mRewriter, *this)
    , mDeleteExprHandler(mRewriter, *this)
    , mFunctionDeclHandler(mRewriter, *this, appConfig.getMethodMatcher())
    , mRecordDeclHandler(mRewriter, *this)

{
  using namespace ast_matchers;
  mMatcher.addMatcher(cxxNewExpr().bind("newStmt"), &mNewExprHandler);
  mMatcher.addMatcher(functionDecl().bind("decl"), &mFunctionDeclHandler);
  mMatcher.addMatcher(cxxRecordDecl().bind("decl"), &mRecordDeclHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cxxStaticCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cxxReinterpretCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new")).bind("fun")),
                               hasAncestor(cStyleCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator new")).bind("fun"))).bind("newStmt"),
      &mOpNewExprHandler);

  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cxxReinterpretCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cxxStaticCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun")),
                               hasAncestor(cStyleCastExpr().bind("castExpr")))
                          .bind("newStmt"),
                      &mOpNewExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator new[]")).bind("fun"))).bind("newStmt"),
      &mOpNewExprHandler);

  mMatcher.addMatcher(cxxDeleteExpr().bind("deleteStmt"), &mDeleteExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator delete")).bind("fun"))).bind("deleteStmt"),
      &mOpDeleteExprHandler);
  mMatcher.addMatcher(
      callExpr(callee(functionDecl(hasName("operator delete[]")).bind("fun"))).bind("deleteStmt"),
      &mOpDeleteExprHandler);
}

void AllocationASTConsumer::HandleTranslationUnit(ASTContext& context) {
  if (mRewriter == nullptr) {
    mRewriter = new clang::Rewriter(context.getSourceManager(), context.getLangOpts());
  }
  mMatcher.matchAST(context);

  if (mAppConfig.shouldPrependInclude()) {
    auto mainFile = context.getSourceManager().getMainFileID();
    auto mainStartLocation = context.getSourceManager().getLocForStartOfFile(mainFile);
    std::string includeStmt;
    for (std::string const& inc : mAppConfig.getPrependInclude(FileType::CPP)) {
      includeStmt += "#include <" + inc + ">\n";
    }
    mRewriter->InsertText(mainStartLocation, includeStmt);
  }

  {
    auto mainFile = context.getSourceManager().getMainFileID();
    auto mainEndLocation = context.getSourceManager().getLocForEndOfFile(mainFile);
    insertSpecializedInformation(*mRewriter, mainEndLocation);
  }

  processRewriterData(mRewriter);
}

void AllocationASTConsumer::processRewriterData(clang::Rewriter*& rewriter) {
  // nop
}

void AllocationASTConsumer::handleSpecializedType(
    clang::QualType const& typeInfo, unsigned specificUniqId,
    SpecializationHandler::PointeeConversion convertToPointee /*=KEEP_ORIGINAL_TYPE*/) {
  clang::LangOptions options;
  clang::PrintingPolicy policy(options);
  policy.SuppressUnwrittenScope = true;
  policy.SuppressTagKeyword = true;

  clang::QualType st = typeInfo;
  if (convertToPointee == CONVERT_TO_POINTEE && !st->getPointeeType().isNull()) {
    st = st->getPointeeType();
  }

  clang::QualType ct = typeInfo;
  if (!ct.isCanonical()) ct = ct.getCanonicalType();
  if (convertToPointee == CONVERT_TO_POINTEE && !ct->getPointeeType().isNull()) {
    ct = ct->getPointeeType();
  }

  mCanonicalSpecializations.insert(ct.getAsString(policy));
  mSpecificSpecializations.insert(
      SpecializedInfo{ct.getAsString(policy), st.getAsString(policy), specificUniqId});
}

void AllocationASTConsumer::insertSpecializedInformation(clang::Rewriter& rewriter,
                                                         clang::SourceLocation pos) const {
  std::string str = "\n\n\n";
  for (std::string const& type : mCanonicalSpecializations) {
    str += "TYPEGRIND_CANONICAL_SPECIALIZATION(TYPEGRIND_TYPE(" + type + "));\n";
  }

  for (auto const& type : mSpecificSpecializations) {
    str += "TYPEGRIND_SPECIFIC_SPECIALIZATION(TYPEGRIND_TYPE(" + type.canonicalName +
           "), TYPEGRIND_TYPE(" + type.specificName + "), " + std::to_string(type.uniqueId) +
           ");\n";
  }

  rewriter.InsertText(pos, str);
}
}
<|endoftext|>


<commit_before>/*=========================================================================

 Program:   openCherry Platform
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) German Cancer Research Center, Division of Medical and
 Biological Informatics. All rights reserved.
 See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/

#include "cherryIDebugObjectListener.h"

#include "cherryDebugUtil.h"
#include "cherryObject.h"
#include "cherryLog.h"
#include "cherryPlatform.h"
#include "cherryDebugBreakpointManager.h"

#include <Poco/Bugcheck.h>
#include <Poco/NumberParser.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/DOMWriter.h>
#include <Poco/SAX/InputSource.h>
#include <Poco/SAX/SAXException.h>

#include <Poco/FileStream.h>

#include <sstream>

#include <numeric>

namespace cherry
{

static IDebugObjectListener::Events _G_ObjectEvents;

const std::string DebugUtil::DEBUG_UTIL_XML = "debugutil.xml";
const std::string DebugUtil::DEBUGUTIL_TAG = "debugutil";
const std::string DebugUtil::TRACEOBJECT_TAG = "traceObject";
const std::string DebugUtil::TRACECLASS_TAG = "traceClass";
const std::string DebugUtil::ID_ATTR = "id";
const std::string DebugUtil::NAME_ATTR = "name";

Poco::HashMap<Poco::UInt32, std::list<unsigned int> >
    DebugUtil::m_TraceIdToSmartPointerMap;
Poco::HashMap<Poco::UInt32, const Object*> DebugUtil::m_TraceIdToObjectMap;
std::set<unsigned int> DebugUtil::m_TracedObjects;
std::set<std::string> DebugUtil::m_TracedClasses;

class NotClassName: public std::unary_function<const Object*, bool>
{

  std::string name;

public:
  NotClassName(const std::string& s) :
    name(s)
  {
  }
  bool operator()(Poco::HashMapEntry<unsigned int, const Object*>& entry) const
  {
    return name != entry.second->GetClassName();
  }
};

class AccumulateClassNames: public std::binary_function<std::set<std::string>*,
    Poco::HashMapEntry<unsigned int, const Object*>&, std::set<std::string>*>
{
public:
  std::set<std::string>* operator()(std::set<std::string>* names,
      Poco::HashMapEntry<unsigned int, const Object*>& entry)
  {
    names->insert(entry.second->GetClassName());
    return names;
  }
};

DebugBreakpointManager* DebugUtil::GetBreakpointManager()
{
  static DebugBreakpointManager breakpointManager;
  return &breakpointManager;
}

void DebugUtil::TraceObject(const Object* object)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << object->GetTraceId() << std::endl;
  m_TracedObjects.insert(object->GetTraceId());
  _G_ObjectEvents.objTracingEvent(object->GetTraceId(), true, object);
#endif
}

void DebugUtil::TraceObject(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << traceId << std::endl;
  m_TracedObjects.insert(traceId);
  TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.find(traceId);
  if (i != m_TraceIdToObjectMap.end())
  _G_ObjectEvents.objTracingEvent(traceId, true, i->second);
  else
  _G_ObjectEvents.objTracingEvent(traceId, true, 0);
#endif
}

void DebugUtil::TraceClass(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << className << std::endl;
  m_TracedClasses.insert(className);
  //_G_ObjectEvents.objTracingEvent(object->GetTraceId(), true, object);
#endif
}

void DebugUtil::StopTracing(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << traceId << std::endl;
  m_TracedObjects.erase(traceId);
  TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.find(traceId);
  if (i != m_TraceIdToObjectMap.end())
  _G_ObjectEvents.objTracingEvent(traceId, false, i->second);
  else
  _G_ObjectEvents.objTracingEvent(traceId, false, 0);
#endif
}

void DebugUtil::StopTracing(const Object* obj)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << obj->GetTraceId() << std::endl;
  m_TracedObjects.erase(obj->GetTraceId());
  _G_ObjectEvents.objTracingEvent(obj->GetTraceId(), false, obj);
#endif
}

void DebugUtil::StopTracing(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << className << std::endl;
  m_TracedClasses.erase(className);
  //_G_ObjectEvents.objTracingEvent(obj->GetTraceId(), false, obj);
#endif
}

bool DebugUtil::IsTraced(const Object* object)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedObjects.find(object->GetTraceId()) != m_TracedObjects.end();
#else
  return false;
#endif
}

bool DebugUtil::IsTraced(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedObjects.find(traceId) != m_TracedObjects.end();
#else
  return false;
#endif
}

bool DebugUtil::IsTraced(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedClasses.find(className) != m_TracedClasses.end();
#else
  return false;
#endif
}

const std::set<unsigned int>& DebugUtil::GetTracedObjects()
{
  return m_TracedObjects;
}

const Object* DebugUtil::GetObject(unsigned int traceId)
{
  return m_TraceIdToObjectMap[traceId];
}

std::list<unsigned int> DebugUtil::GetSmartPointerIDs(
    const Object* objectPointer, const std::list<unsigned int>& excludeList)
{
  poco_assert(objectPointer != 0)
;#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  std::list<unsigned int> ids = m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()];
  for (std::list<unsigned int>::const_iterator iter = excludeList.begin();
      iter != excludeList.end(); ++iter)
  ids.remove(*iter);
  return ids;
#else
  return std::list<unsigned int>();
#endif
}

void DebugUtil::GetRegisteredObjects(std::vector<const Object*>& list)
{
  for (TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.begin();
      i != m_TraceIdToObjectMap.end(); ++i)
  {
    list.push_back(i->second);
  }
}

void DebugUtil::PrintSmartPointerIDs(const Object* objectPointer, std::ostream& stream, const std::list<unsigned int>& excludeList)
{
  stream << "SmartPointer IDs [ ";
  std::list<unsigned int> ids = GetSmartPointerIDs(objectPointer, excludeList);
  for (std::list<unsigned int>::const_iterator iter = ids.begin();
      iter != ids.end(); ++iter)
  {
    stream << *iter << " ";
  }
  stream << "]\n";
}

void DebugUtil::AddObjectListener(SmartPointer<IDebugObjectListener> listener)
{
  _G_ObjectEvents.AddListener(listener);
}

void DebugUtil::RemoveObjectListener(SmartPointer<IDebugObjectListener> listener)
{
  _G_ObjectEvents.RemoveListener(listener);
}

void DebugUtil::ResetObjectSummary()
{
  m_TraceIdToObjectMap.clear();
  m_TraceIdToSmartPointerMap.clear();
  m_TracedObjects.clear();
  m_TracedClasses.clear();
}

bool DebugUtil::PrintObjectSummary(bool details)
{
  std::set<std::string> names;
  std::accumulate(m_TraceIdToObjectMap.begin(), m_TraceIdToObjectMap.end(), &names, AccumulateClassNames());

  if (!names.empty())
  {
    std::cout << std::endl << std::endl << "#########################################################" << std::endl;
    std::cout << "########     cherry::Object leakage summary:     ########" << std::endl << std::endl;

    for (std::set<std::string>::const_iterator i = names.begin();
        i != names.end(); ++i)
    {
      PrintObjectSummary(*i, details);
      if (details) std::cout << std::endl;
    }

    std::cout << std::endl << "#########################################################" << std::endl << std::endl;
  }

  return !names.empty();
}

bool DebugUtil::PrintObjectSummary(const std::string& className, bool details)
{
  TraceIdToObjectType::ConstIterator endIter =
  std::remove_if(m_TraceIdToObjectMap.begin(), m_TraceIdToObjectMap.end(), NotClassName(className));

  std::cout << "Class: " << className;
  if (details) std::cout << std::endl;

  std::size_t count = 0;
  for (TraceIdToObjectType::ConstIterator iter = m_TraceIdToObjectMap.begin();
      iter != endIter; ++iter, ++count)
  {
    if (details)
    {
      std::cout << *(iter->second);
    }
  }
  std::cout << " (" << count << " instances)" << std::endl;
  return (count!=0);
}

unsigned int& DebugUtil::GetSmartPointerCounter()
{
  static unsigned int counter = 0;
  return counter;
}

void DebugUtil::UnregisterSmartPointer(unsigned int smartPointerId, const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  poco_assert(objectPointer != 0);

  m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()].remove(smartPointerId);
  _G_ObjectEvents.spDestroyedEvent(smartPointerId, objectPointer);
#endif
}

void DebugUtil::RegisterSmartPointer(unsigned int smartPointerId, const Object* objectPointer, bool /*recordStack*/)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  poco_assert(objectPointer != 0);

  if (m_TracedClasses.find(objectPointer->GetClassName()) != m_TracedClasses.end() ||
      m_TracedObjects.find(objectPointer->GetTraceId()) != m_TracedObjects.end())
  {
    m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()].push_back(smartPointerId);
    _G_ObjectEvents.spCreatedEvent(smartPointerId, objectPointer);
  }

  if (GetBreakpointManager()->BreakAtSmartpointer(smartPointerId))
  poco_debugger_msg("SmartPointer Breakpoint reached");
#endif
}

void DebugUtil::RegisterObject(const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  m_TraceIdToObjectMap.insert(std::make_pair(objectPointer->GetTraceId(), objectPointer));
  _G_ObjectEvents.objCreatedEvent(objectPointer);

  if (GetBreakpointManager()->BreakAtObject(objectPointer->GetTraceId()))
  poco_debugger_msg("SmartPointer Breakpoint reached");
#endif
}

void DebugUtil::UnregisterObject(const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  m_TraceIdToObjectMap.erase(objectPointer->GetTraceId());
  _G_ObjectEvents.objDestroyedEvent(objectPointer);
#endif
}

bool DebugUtil::GetPersistencePath(Poco::Path& path)
{
  return Platform::GetStatePath(path, Platform::GetBundle("system.bundle"));
}

void DebugUtil::SaveState()
{
  Poco::Path path;
  if (!GetPersistencePath(path)) return;

  path.setFileName(DEBUG_UTIL_XML);

  Poco::XML::Document* doc = new Poco::XML::Document();
  Poco::XML::Element* debugutil = doc->createElement(DEBUGUTIL_TAG);
  doc->appendChild(debugutil)->release();

  for (std::set<unsigned int>::const_iterator i = m_TracedObjects.begin();
      i != m_TracedObjects.end(); ++i)
  {
    Poco::XML::Element* traceObject = doc->createElement(TRACEOBJECT_TAG);
    debugutil->appendChild(traceObject)->release();
    std::stringstream ss;
    ss << *i;
    traceObject->setAttribute(ID_ATTR, ss.str());
  }

  for (std::set<std::string>::const_iterator i = m_TracedClasses.begin();
      i != m_TracedClasses.end(); ++i)
  {
    Poco::XML::Element* traceClass = doc->createElement(TRACECLASS_TAG);
    debugutil->appendChild(traceClass)->release();
    traceClass->setAttribute(NAME_ATTR, *i);
  }

  try
  {
    Poco::FileOutputStream writer(path.toString());
    Poco::XML::DOMWriter out;
    out.setOptions(3); //write declaration and pretty print
    out.writeNode(writer, doc);

    doc->release();

    // save BreakpointManager
    path.setFileName(DebugBreakpointManager::BREAKPOINTS_XML);
    GetBreakpointManager()->SaveState(path);
  }
  catch (Poco::FileException& e)
  {
    CHERRY_WARN << e.displayText();
  }

}

void DebugUtil::RestoreState()
{
  Poco::Path path;
  if (!GetPersistencePath(path)) return;

  path.setFileName(DEBUG_UTIL_XML);

  try
  {
    Poco::XML::DOMParser parser;

    Poco::FileInputStream reader(path.toString());
    Poco::XML::InputSource source(reader);

    //source.setSystemId(baseDir);
    Poco::XML::Document* doc = parser.parse(&source);
    Poco::XML::Element* debugutil = doc->documentElement();

    if (debugutil)
    {
      // restore traced objects
      Poco::XML::NodeList* elementList = debugutil->getElementsByTagName(TRACEOBJECT_TAG);
      for (std::size_t i = 0; i < elementList->length(); i++)
      {
        Poco::XML::Element* elem =
        dynamic_cast<Poco::XML::Element*> (elementList->item(i));

        if (!elem->hasAttribute(ID_ATTR)) continue;

        const std::string& attr = elem->getAttribute(ID_ATTR);

        int traceId = 0;
        try
        {
          traceId = Poco::NumberParser::parse(attr);
        }
        catch (const Poco::SyntaxException& e)
        {
          CHERRY_WARN << e.displayText();
        }

        DebugUtil::TraceObject(traceId);
      }
      elementList->release();

      // restore traced classes
      elementList = debugutil->getElementsByTagName(TRACECLASS_TAG);
      for (std::size_t i = 0; i < elementList->length(); i++)
      {
        Poco::XML::Element* elem =
        dynamic_cast<Poco::XML::Element*> (elementList->item(i));

        if (!elem->hasAttribute(NAME_ATTR)) continue;

        const std::string& traceClass = elem->getAttribute(NAME_ATTR);
        if (!traceClass.empty())
        DebugUtil::TraceClass(traceClass);
      }
      elementList->release();

      debugutil->release();
    }

    doc->release();
  }
  catch (Poco::XML::SAXParseException& e)
  {
    CHERRY_WARN << e.displayText();
  }

  // restore BreakpointManager
  path.setFileName(DebugBreakpointManager::BREAKPOINTS_XML);
  GetBreakpointManager()->RestoreState(path);
}

}
<commit_msg>COMP: fixing ";" due to automatic source code formatting<commit_after>/*=========================================================================

 Program:   openCherry Platform
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) German Cancer Research Center, Division of Medical and
 Biological Informatics. All rights reserved.
 See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/

#include "cherryIDebugObjectListener.h"

#include "cherryDebugUtil.h"
#include "cherryObject.h"
#include "cherryLog.h"
#include "cherryPlatform.h"
#include "cherryDebugBreakpointManager.h"

#include <Poco/Bugcheck.h>
#include <Poco/NumberParser.h>
#include <Poco/DOM/NodeList.h>
#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Element.h>
#include <Poco/DOM/DOMWriter.h>
#include <Poco/SAX/InputSource.h>
#include <Poco/SAX/SAXException.h>

#include <Poco/FileStream.h>

#include <sstream>

#include <numeric>

namespace cherry
{

static IDebugObjectListener::Events _G_ObjectEvents;

const std::string DebugUtil::DEBUG_UTIL_XML = "debugutil.xml";
const std::string DebugUtil::DEBUGUTIL_TAG = "debugutil";
const std::string DebugUtil::TRACEOBJECT_TAG = "traceObject";
const std::string DebugUtil::TRACECLASS_TAG = "traceClass";
const std::string DebugUtil::ID_ATTR = "id";
const std::string DebugUtil::NAME_ATTR = "name";

Poco::HashMap<Poco::UInt32, std::list<unsigned int> >
    DebugUtil::m_TraceIdToSmartPointerMap;
Poco::HashMap<Poco::UInt32, const Object*> DebugUtil::m_TraceIdToObjectMap;
std::set<unsigned int> DebugUtil::m_TracedObjects;
std::set<std::string> DebugUtil::m_TracedClasses;

class NotClassName: public std::unary_function<const Object*, bool>
{

  std::string name;

public:
  NotClassName(const std::string& s) :
    name(s)
  {
  }
  bool operator()(Poco::HashMapEntry<unsigned int, const Object*>& entry) const
  {
    return name != entry.second->GetClassName();
  }
};

class AccumulateClassNames: public std::binary_function<std::set<std::string>*,
    Poco::HashMapEntry<unsigned int, const Object*>&, std::set<std::string>*>
{
public:
  std::set<std::string>* operator()(std::set<std::string>* names,
      Poco::HashMapEntry<unsigned int, const Object*>& entry)
  {
    names->insert(entry.second->GetClassName());
    return names;
  }
};

DebugBreakpointManager* DebugUtil::GetBreakpointManager()
{
  static DebugBreakpointManager breakpointManager;
  return &breakpointManager;
}

void DebugUtil::TraceObject(const Object* object)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << object->GetTraceId() << std::endl;
  m_TracedObjects.insert(object->GetTraceId());
  _G_ObjectEvents.objTracingEvent(object->GetTraceId(), true, object);
#endif
}

void DebugUtil::TraceObject(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << traceId << std::endl;
  m_TracedObjects.insert(traceId);
  TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.find(traceId);
  if (i != m_TraceIdToObjectMap.end())
  _G_ObjectEvents.objTracingEvent(traceId, true, i->second);
  else
  _G_ObjectEvents.objTracingEvent(traceId, true, 0);
#endif
}

void DebugUtil::TraceClass(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing enabled for: " << className << std::endl;
  m_TracedClasses.insert(className);
  //_G_ObjectEvents.objTracingEvent(object->GetTraceId(), true, object);
#endif
}

void DebugUtil::StopTracing(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << traceId << std::endl;
  m_TracedObjects.erase(traceId);
  TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.find(traceId);
  if (i != m_TraceIdToObjectMap.end())
  _G_ObjectEvents.objTracingEvent(traceId, false, i->second);
  else
  _G_ObjectEvents.objTracingEvent(traceId, false, 0);
#endif
}

void DebugUtil::StopTracing(const Object* obj)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << obj->GetTraceId() << std::endl;
  m_TracedObjects.erase(obj->GetTraceId());
  _G_ObjectEvents.objTracingEvent(obj->GetTraceId(), false, obj);
#endif
}

void DebugUtil::StopTracing(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  CHERRY_INFO << "Tracing stopped for: " << className << std::endl;
  m_TracedClasses.erase(className);
  //_G_ObjectEvents.objTracingEvent(obj->GetTraceId(), false, obj);
#endif
}

bool DebugUtil::IsTraced(const Object* object)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedObjects.find(object->GetTraceId()) != m_TracedObjects.end();
#else
  return false;
#endif
}

bool DebugUtil::IsTraced(unsigned int traceId)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedObjects.find(traceId) != m_TracedObjects.end();
#else
  return false;
#endif
}

bool DebugUtil::IsTraced(const std::string& className)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  return m_TracedClasses.find(className) != m_TracedClasses.end();
#else
  return false;
#endif
}

const std::set<unsigned int>& DebugUtil::GetTracedObjects()
{
  return m_TracedObjects;
}

const Object* DebugUtil::GetObject(unsigned int traceId)
{
  return m_TraceIdToObjectMap[traceId];
}

std::list<unsigned int> DebugUtil::GetSmartPointerIDs(
    const Object* objectPointer, const std::list<unsigned int>& excludeList)
{
  poco_assert(objectPointer != 0);
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  std::list<unsigned int> ids = m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()];
  for (std::list<unsigned int>::const_iterator iter = excludeList.begin();
      iter != excludeList.end(); ++iter)
  ids.remove(*iter);
  return ids;
#else
  return std::list<unsigned int>();
#endif
}

void DebugUtil::GetRegisteredObjects(std::vector<const Object*>& list)
{
  for (TraceIdToObjectType::ConstIterator i = m_TraceIdToObjectMap.begin();
      i != m_TraceIdToObjectMap.end(); ++i)
  {
    list.push_back(i->second);
  }
}

void DebugUtil::PrintSmartPointerIDs(const Object* objectPointer, std::ostream& stream, const std::list<unsigned int>& excludeList)
{
  stream << "SmartPointer IDs [ ";
  std::list<unsigned int> ids = GetSmartPointerIDs(objectPointer, excludeList);
  for (std::list<unsigned int>::const_iterator iter = ids.begin();
      iter != ids.end(); ++iter)
  {
    stream << *iter << " ";
  }
  stream << "]\n";
}

void DebugUtil::AddObjectListener(SmartPointer<IDebugObjectListener> listener)
{
  _G_ObjectEvents.AddListener(listener);
}

void DebugUtil::RemoveObjectListener(SmartPointer<IDebugObjectListener> listener)
{
  _G_ObjectEvents.RemoveListener(listener);
}

void DebugUtil::ResetObjectSummary()
{
  m_TraceIdToObjectMap.clear();
  m_TraceIdToSmartPointerMap.clear();
  m_TracedObjects.clear();
  m_TracedClasses.clear();
}

bool DebugUtil::PrintObjectSummary(bool details)
{
  std::set<std::string> names;
  std::accumulate(m_TraceIdToObjectMap.begin(), m_TraceIdToObjectMap.end(), &names, AccumulateClassNames());

  if (!names.empty())
  {
    std::cout << std::endl << std::endl << "#########################################################" << std::endl;
    std::cout << "########     cherry::Object leakage summary:     ########" << std::endl << std::endl;

    for (std::set<std::string>::const_iterator i = names.begin();
        i != names.end(); ++i)
    {
      PrintObjectSummary(*i, details);
      if (details) std::cout << std::endl;
    }

    std::cout << std::endl << "#########################################################" << std::endl << std::endl;
  }

  return !names.empty();
}

bool DebugUtil::PrintObjectSummary(const std::string& className, bool details)
{
  TraceIdToObjectType::ConstIterator endIter =
  std::remove_if(m_TraceIdToObjectMap.begin(), m_TraceIdToObjectMap.end(), NotClassName(className));

  std::cout << "Class: " << className;
  if (details) std::cout << std::endl;

  std::size_t count = 0;
  for (TraceIdToObjectType::ConstIterator iter = m_TraceIdToObjectMap.begin();
      iter != endIter; ++iter, ++count)
  {
    if (details)
    {
      std::cout << *(iter->second);
    }
  }
  std::cout << " (" << count << " instances)" << std::endl;
  return (count!=0);
}

unsigned int& DebugUtil::GetSmartPointerCounter()
{
  static unsigned int counter = 0;
  return counter;
}

void DebugUtil::UnregisterSmartPointer(unsigned int smartPointerId, const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  poco_assert(objectPointer != 0);

  m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()].remove(smartPointerId);
  _G_ObjectEvents.spDestroyedEvent(smartPointerId, objectPointer);
#endif
}

void DebugUtil::RegisterSmartPointer(unsigned int smartPointerId, const Object* objectPointer, bool /*recordStack*/)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  poco_assert(objectPointer != 0);

  if (m_TracedClasses.find(objectPointer->GetClassName()) != m_TracedClasses.end() ||
      m_TracedObjects.find(objectPointer->GetTraceId()) != m_TracedObjects.end())
  {
    m_TraceIdToSmartPointerMap[objectPointer->GetTraceId()].push_back(smartPointerId);
    _G_ObjectEvents.spCreatedEvent(smartPointerId, objectPointer);
  }

  if (GetBreakpointManager()->BreakAtSmartpointer(smartPointerId))
  poco_debugger_msg("SmartPointer Breakpoint reached");
#endif
}

void DebugUtil::RegisterObject(const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  m_TraceIdToObjectMap.insert(std::make_pair(objectPointer->GetTraceId(), objectPointer));
  _G_ObjectEvents.objCreatedEvent(objectPointer);

  if (GetBreakpointManager()->BreakAtObject(objectPointer->GetTraceId()))
  poco_debugger_msg("SmartPointer Breakpoint reached");
#endif
}

void DebugUtil::UnregisterObject(const Object* objectPointer)
{
#ifdef OPENCHERRY_DEBUG_SMARTPOINTER
  m_TraceIdToObjectMap.erase(objectPointer->GetTraceId());
  _G_ObjectEvents.objDestroyedEvent(objectPointer);
#endif
}

bool DebugUtil::GetPersistencePath(Poco::Path& path)
{
  return Platform::GetStatePath(path, Platform::GetBundle("system.bundle"));
}

void DebugUtil::SaveState()
{
  Poco::Path path;
  if (!GetPersistencePath(path)) return;

  path.setFileName(DEBUG_UTIL_XML);

  Poco::XML::Document* doc = new Poco::XML::Document();
  Poco::XML::Element* debugutil = doc->createElement(DEBUGUTIL_TAG);
  doc->appendChild(debugutil)->release();

  for (std::set<unsigned int>::const_iterator i = m_TracedObjects.begin();
      i != m_TracedObjects.end(); ++i)
  {
    Poco::XML::Element* traceObject = doc->createElement(TRACEOBJECT_TAG);
    debugutil->appendChild(traceObject)->release();
    std::stringstream ss;
    ss << *i;
    traceObject->setAttribute(ID_ATTR, ss.str());
  }

  for (std::set<std::string>::const_iterator i = m_TracedClasses.begin();
      i != m_TracedClasses.end(); ++i)
  {
    Poco::XML::Element* traceClass = doc->createElement(TRACECLASS_TAG);
    debugutil->appendChild(traceClass)->release();
    traceClass->setAttribute(NAME_ATTR, *i);
  }

  try
  {
    Poco::FileOutputStream writer(path.toString());
    Poco::XML::DOMWriter out;
    out.setOptions(3); //write declaration and pretty print
    out.writeNode(writer, doc);

    doc->release();

    // save BreakpointManager
    path.setFileName(DebugBreakpointManager::BREAKPOINTS_XML);
    GetBreakpointManager()->SaveState(path);
  }
  catch (Poco::FileException& e)
  {
    CHERRY_WARN << e.displayText();
  }

}

void DebugUtil::RestoreState()
{
  Poco::Path path;
  if (!GetPersistencePath(path)) return;

  path.setFileName(DEBUG_UTIL_XML);

  try
  {
    Poco::XML::DOMParser parser;

    Poco::FileInputStream reader(path.toString());
    Poco::XML::InputSource source(reader);

    //source.setSystemId(baseDir);
    Poco::XML::Document* doc = parser.parse(&source);
    Poco::XML::Element* debugutil = doc->documentElement();

    if (debugutil)
    {
      // restore traced objects
      Poco::XML::NodeList* elementList = debugutil->getElementsByTagName(TRACEOBJECT_TAG);
      for (std::size_t i = 0; i < elementList->length(); i++)
      {
        Poco::XML::Element* elem =
        dynamic_cast<Poco::XML::Element*> (elementList->item(i));

        if (!elem->hasAttribute(ID_ATTR)) continue;

        const std::string& attr = elem->getAttribute(ID_ATTR);

        int traceId = 0;
        try
        {
          traceId = Poco::NumberParser::parse(attr);
        }
        catch (const Poco::SyntaxException& e)
        {
          CHERRY_WARN << e.displayText();
        }

        DebugUtil::TraceObject(traceId);
      }
      elementList->release();

      // restore traced classes
      elementList = debugutil->getElementsByTagName(TRACECLASS_TAG);
      for (std::size_t i = 0; i < elementList->length(); i++)
      {
        Poco::XML::Element* elem =
        dynamic_cast<Poco::XML::Element*> (elementList->item(i));

        if (!elem->hasAttribute(NAME_ATTR)) continue;

        const std::string& traceClass = elem->getAttribute(NAME_ATTR);
        if (!traceClass.empty())
        DebugUtil::TraceClass(traceClass);
      }
      elementList->release();

      debugutil->release();
    }

    doc->release();
  }
  catch (Poco::XML::SAXParseException& e)
  {
    CHERRY_WARN << e.displayText();
  }

  // restore BreakpointManager
  path.setFileName(DebugBreakpointManager::BREAKPOINTS_XML);
  GetBreakpointManager()->RestoreState(path);
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
#include "bearerdialog.h"
#include "sessionwidget.h"

#include <QDebug>

#ifdef Q_OS_WIN
#include <winsock2.h>
#undef interface
#endif

BearerDialog::BearerDialog(QWidget *parent)
:   QDialog(parent)
{
    setupUi(this);
    delete tabWidget->currentWidget();
    sessionGroup->hide();

    updateConfigurations();

    onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty());

    QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
    for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
        QTreeWidgetItem *item = treeWidget->topLevelItem(i);

        if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) {
            treeWidget->setCurrentItem(item);
            showConfigurationFor(item);
            break;
        }
    }

    connect(&manager, SIGNAL(configurationAdded(const QNetworkConfiguration&)),
            this, SLOT(configurationAdded(const QNetworkConfiguration&)));
    connect(&manager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)),
            this, SLOT(configurationRemoved(const QNetworkConfiguration&)));
    connect(&manager, SIGNAL(configurationChanged(const QNetworkConfiguration&)),
            this, SLOT(configurationChanged(const QNetworkConfiguration)));
    connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations()));
    connect(&manager, SIGNAL(onlineStateChanged(bool)), this ,SLOT(onlineStateChanged(bool)));

#ifdef Q_OS_WIN
    connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork()));
    connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork()));
#else
    nlaGroup->hide();
#endif

    connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
            this, SLOT(createSessionFor(QTreeWidgetItem*)));

    connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
            this, SLOT(showConfigurationFor(QTreeWidgetItem*)));

    connect(newSessionButton, SIGNAL(clicked()),
            this, SLOT(createNewSession()));
    connect(deleteSessionButton, SIGNAL(clicked()),
            this, SLOT(deleteSession()));

    connect(scanButton, SIGNAL(clicked()),
            this, SLOT(performScan()));
}

BearerDialog::~BearerDialog()
{
}

static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config)
{
    item->setText(0, config.name());
    item->setData(0, Qt::UserRole, config.identifier());

    QFont font = item->font(1);
    font.setBold((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active);
    item->setFont(0, font);
}

void BearerDialog::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
{
    QTreeWidgetItem *item = new QTreeWidgetItem;
    updateItem(item, config);

    if (parent)
        parent->addChild(item);
    else
        treeWidget->addTopLevelItem(item);

    if (config.type() == QNetworkConfiguration::ServiceNetwork) {
        foreach (const QNetworkConfiguration &child, config.children())
            configurationAdded(child, item);
    }
}

void BearerDialog::configurationAdded(const QNetworkConfiguration &config)
{
    configurationAdded(config, 0);
}

void BearerDialog::configurationRemoved(const QNetworkConfiguration &config)
{
    QList<QTreeWidgetItem *> items = treeWidget->findItems(config.name(), Qt::MatchExactly);

    while (!items.isEmpty())
        delete treeWidget->takeTopLevelItem(treeWidget->indexOfTopLevelItem(items.takeFirst()));
}

void BearerDialog::configurationChanged(const QNetworkConfiguration &config)
{
    QList<QTreeWidgetItem *> items = treeWidget->findItems(config.name(), Qt::MatchExactly);

    while (!items.isEmpty()) {
        QTreeWidgetItem *item = items.takeFirst();

        if (item) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);

            if (item == treeWidget->currentItem())
                showConfigurationFor(item);
        }
    }
}

void BearerDialog::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap)
{
    QMap<QString, QTreeWidgetItem *> itemMap;
    for (int i = 0; i < parent->childCount(); ++i) {
        QTreeWidgetItem *item = parent->child(i);
        itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
    }

    QList<QNetworkConfiguration> allConfigurations = snap.children();

    while (!allConfigurations.isEmpty()) {
        QNetworkConfiguration config = allConfigurations.takeFirst();

        QTreeWidgetItem *item = itemMap.take(config.identifier());
        if (item) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);
        } else {
            configurationAdded(config, parent);
        }
    }

    foreach (const QString &id, itemMap.keys())
        delete itemMap.value(id);

    itemMap.clear();
}

void BearerDialog::updateConfigurations()
{
    progressBar->hide();
    scanButton->show();

    QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard);
    QMap<QString, QTreeWidgetItem *> itemMap;
    while (!items.isEmpty()) {
        QTreeWidgetItem *item = items.takeFirst();
        itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
    }

    QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();

    while (!allConfigurations.isEmpty()) {
        QNetworkConfiguration config = allConfigurations.takeFirst();

        QTreeWidgetItem *item = itemMap.take(config.identifier());
        if (item) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);
        } else {
            configurationAdded(config);
        }
    }

    foreach (const QString &id, itemMap.keys())
        delete itemMap.value(id);
}

void BearerDialog::onlineStateChanged(bool isOnline)
{
    if (isOnline)
        onlineState->setText(tr("Online"));
    else
        onlineState->setText(tr("Offline"));
}

#ifdef Q_OS_WIN
void BearerDialog::registerNetwork()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    QNetworkConfiguration configuration =
        manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());

    const QString name = configuration.name();

    qDebug() << "Registering" << name << "with system";

    WSAQUERYSET networkInfo;
    memset(&networkInfo, 0, sizeof(networkInfo));
    networkInfo.dwSize = sizeof(networkInfo);
    networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
    networkInfo.dwNameSpace = NS_NLA;

    if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
        qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError();
}

void BearerDialog::unregisterNetwork()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    QNetworkConfiguration configuration =
        manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());

    const QString name = configuration.name();

    qDebug() << "Unregistering" << name << "with system";

    WSAQUERYSET networkInfo;
    memset(&networkInfo, 0, sizeof(networkInfo));
    networkInfo.dwSize = sizeof(networkInfo);
    networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
    networkInfo.dwNameSpace = NS_NLA;

    if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
        qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
}
#endif

void BearerDialog::showConfigurationFor(QTreeWidgetItem *item)
{
    QString identifier;

    if (item)
        identifier = item->data(0, Qt::UserRole).toString();

    QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);

    switch (conf.state()) {
    case QNetworkConfiguration::Active:
        configurationState->setText(tr("Active"));
        break;
    case QNetworkConfiguration::Discovered:
        configurationState->setText(tr("Discovered"));
        break;
    case QNetworkConfiguration::Defined:
        configurationState->setText(tr("Defined"));
        break;
    case QNetworkConfiguration::Undefined:
        configurationState->setText(tr("Undefined"));
        break;
    default:
        configurationState->setText(QString());
    }

    switch (conf.type()) {
    case QNetworkConfiguration::InternetAccessPoint:
        configurationType->setText(tr("Internet Access Point"));
        break;
    case QNetworkConfiguration::ServiceNetwork:
        configurationType->setText(tr("Service Network"));
        break;
    case QNetworkConfiguration::UserChoice:
        configurationType->setText(tr("User Choice"));
        break;
    case QNetworkConfiguration::Invalid:
        configurationType->setText(tr("Invalid"));
        break;
    default:
        configurationType->setText(QString());
    }

    switch (conf.purpose()) {
    case QNetworkConfiguration::Unknown:
        configurationPurpose->setText(tr("Unknown"));
        break;
    case QNetworkConfiguration::Public:
        configurationPurpose->setText(tr("Public"));
        break;
    case QNetworkConfiguration::Private:
        configurationPurpose->setText(tr("Private"));
        break;
    case QNetworkConfiguration::ServiceSpecific:
        configurationPurpose->setText(tr("Service Specific"));
        break;
    default:
        configurationPurpose->setText(QString());
    }

    configurationIdentifier->setText(conf.identifier());

    configurationRoaming->setText(conf.roamingAvailable() ? tr("Available") : tr("Not available"));

    configurationChildren->setText(QString::number(conf.children().count()));

    configurationName->setText(conf.name());
}

void BearerDialog::createSessionFor(QTreeWidgetItem *item)
{
    const QString identifier = item->data(0, Qt::UserRole).toString();

    QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);

    SessionWidget *session = new SessionWidget(conf);

    tabWidget->addTab(session, conf.name());

    sessionGroup->show();

    sessionWidgets.append(session);
}

void BearerDialog::createNewSession()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    createSessionFor(item);
}

void BearerDialog::deleteSession()
{
    SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget());
    if (session) {
        sessionWidgets.removeAll(session);

        delete session;

        if (tabWidget->count() == 0)
            sessionGroup->hide();
    }
}

void BearerDialog::performScan()
{
    scanButton->hide();
    progressBar->show();
    manager.updateConfigurations();
}

<commit_msg>Fix bearermonitor list view not updating correctly.<commit_after>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
#include "bearerdialog.h"
#include "sessionwidget.h"

#include <QDebug>

#ifdef Q_OS_WIN
#include <winsock2.h>
#undef interface
#endif

BearerDialog::BearerDialog(QWidget *parent)
:   QDialog(parent)
{
    setupUi(this);
    delete tabWidget->currentWidget();
    sessionGroup->hide();

    updateConfigurations();

    onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty());

    QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
    for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
        QTreeWidgetItem *item = treeWidget->topLevelItem(i);

        if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) {
            treeWidget->setCurrentItem(item);
            showConfigurationFor(item);
            break;
        }
    }

    connect(&manager, SIGNAL(configurationAdded(const QNetworkConfiguration&)),
            this, SLOT(configurationAdded(const QNetworkConfiguration&)));
    connect(&manager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)),
            this, SLOT(configurationRemoved(const QNetworkConfiguration&)));
    connect(&manager, SIGNAL(configurationChanged(const QNetworkConfiguration&)),
            this, SLOT(configurationChanged(const QNetworkConfiguration)));
    connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations()));
    connect(&manager, SIGNAL(onlineStateChanged(bool)), this ,SLOT(onlineStateChanged(bool)));

#ifdef Q_OS_WIN
    connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork()));
    connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork()));
#else
    nlaGroup->hide();
#endif

    connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
            this, SLOT(createSessionFor(QTreeWidgetItem*)));

    connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
            this, SLOT(showConfigurationFor(QTreeWidgetItem*)));

    connect(newSessionButton, SIGNAL(clicked()),
            this, SLOT(createNewSession()));
    connect(deleteSessionButton, SIGNAL(clicked()),
            this, SLOT(deleteSession()));

    connect(scanButton, SIGNAL(clicked()),
            this, SLOT(performScan()));
}

BearerDialog::~BearerDialog()
{
}

static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config)
{
    item->setText(0, config.name());
    item->setData(0, Qt::UserRole, config.identifier());

    QFont font = item->font(1);
    font.setBold((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active);
    item->setFont(0, font);
}

void BearerDialog::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
{
    QTreeWidgetItem *item = new QTreeWidgetItem;
    updateItem(item, config);

    if (parent)
        parent->addChild(item);
    else
        treeWidget->addTopLevelItem(item);

    if (config.type() == QNetworkConfiguration::ServiceNetwork) {
        foreach (const QNetworkConfiguration &child, config.children())
            configurationAdded(child, item);
    }
}

void BearerDialog::configurationAdded(const QNetworkConfiguration &config)
{
    configurationAdded(config, 0);
}

void BearerDialog::configurationRemoved(const QNetworkConfiguration &config)
{
    for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
        QTreeWidgetItem *item = treeWidget->topLevelItem(i);

        if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
            delete item;
            break;
        }
    }
}

void BearerDialog::configurationChanged(const QNetworkConfiguration &config)
{
    for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
        QTreeWidgetItem *item = treeWidget->topLevelItem(i);

        if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);

            if (item == treeWidget->currentItem())
                showConfigurationFor(item);

            break;
        }
    }
}

void BearerDialog::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap)
{
    QMap<QString, QTreeWidgetItem *> itemMap;
    for (int i = 0; i < parent->childCount(); ++i) {
        QTreeWidgetItem *item = parent->child(i);
        itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
    }

    QList<QNetworkConfiguration> allConfigurations = snap.children();

    while (!allConfigurations.isEmpty()) {
        QNetworkConfiguration config = allConfigurations.takeFirst();

        QTreeWidgetItem *item = itemMap.take(config.identifier());
        if (item) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);
        } else {
            configurationAdded(config, parent);
        }
    }

    foreach (const QString &id, itemMap.keys())
        delete itemMap.value(id);

    itemMap.clear();
}

void BearerDialog::updateConfigurations()
{
    progressBar->hide();
    scanButton->show();

    QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard);
    QMap<QString, QTreeWidgetItem *> itemMap;
    while (!items.isEmpty()) {
        QTreeWidgetItem *item = items.takeFirst();
        itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
    }

    QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();

    while (!allConfigurations.isEmpty()) {
        QNetworkConfiguration config = allConfigurations.takeFirst();

        QTreeWidgetItem *item = itemMap.take(config.identifier());
        if (item) {
            updateItem(item, config);

            if (config.type() == QNetworkConfiguration::ServiceNetwork)
                updateSnapConfiguration(item, config);
        } else {
            configurationAdded(config);
        }
    }

    foreach (const QString &id, itemMap.keys())
        delete itemMap.value(id);
}

void BearerDialog::onlineStateChanged(bool isOnline)
{
    if (isOnline)
        onlineState->setText(tr("Online"));
    else
        onlineState->setText(tr("Offline"));
}

#ifdef Q_OS_WIN
void BearerDialog::registerNetwork()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    QNetworkConfiguration configuration =
        manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());

    const QString name = configuration.name();

    qDebug() << "Registering" << name << "with system";

    WSAQUERYSET networkInfo;
    memset(&networkInfo, 0, sizeof(networkInfo));
    networkInfo.dwSize = sizeof(networkInfo);
    networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
    networkInfo.dwNameSpace = NS_NLA;

    if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
        qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError();
}

void BearerDialog::unregisterNetwork()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    QNetworkConfiguration configuration =
        manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());

    const QString name = configuration.name();

    qDebug() << "Unregistering" << name << "with system";

    WSAQUERYSET networkInfo;
    memset(&networkInfo, 0, sizeof(networkInfo));
    networkInfo.dwSize = sizeof(networkInfo);
    networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
    networkInfo.dwNameSpace = NS_NLA;

    if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
        qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
}
#endif

void BearerDialog::showConfigurationFor(QTreeWidgetItem *item)
{
    QString identifier;

    if (item)
        identifier = item->data(0, Qt::UserRole).toString();

    QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);

    switch (conf.state()) {
    case QNetworkConfiguration::Active:
        configurationState->setText(tr("Active"));
        break;
    case QNetworkConfiguration::Discovered:
        configurationState->setText(tr("Discovered"));
        break;
    case QNetworkConfiguration::Defined:
        configurationState->setText(tr("Defined"));
        break;
    case QNetworkConfiguration::Undefined:
        configurationState->setText(tr("Undefined"));
        break;
    default:
        configurationState->setText(QString());
    }

    switch (conf.type()) {
    case QNetworkConfiguration::InternetAccessPoint:
        configurationType->setText(tr("Internet Access Point"));
        break;
    case QNetworkConfiguration::ServiceNetwork:
        configurationType->setText(tr("Service Network"));
        break;
    case QNetworkConfiguration::UserChoice:
        configurationType->setText(tr("User Choice"));
        break;
    case QNetworkConfiguration::Invalid:
        configurationType->setText(tr("Invalid"));
        break;
    default:
        configurationType->setText(QString());
    }

    switch (conf.purpose()) {
    case QNetworkConfiguration::Unknown:
        configurationPurpose->setText(tr("Unknown"));
        break;
    case QNetworkConfiguration::Public:
        configurationPurpose->setText(tr("Public"));
        break;
    case QNetworkConfiguration::Private:
        configurationPurpose->setText(tr("Private"));
        break;
    case QNetworkConfiguration::ServiceSpecific:
        configurationPurpose->setText(tr("Service Specific"));
        break;
    default:
        configurationPurpose->setText(QString());
    }

    configurationIdentifier->setText(conf.identifier());

    configurationRoaming->setText(conf.roamingAvailable() ? tr("Available") : tr("Not available"));

    configurationChildren->setText(QString::number(conf.children().count()));

    configurationName->setText(conf.name());
}

void BearerDialog::createSessionFor(QTreeWidgetItem *item)
{
    const QString identifier = item->data(0, Qt::UserRole).toString();

    QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);

    SessionWidget *session = new SessionWidget(conf);

    tabWidget->addTab(session, conf.name());

    sessionGroup->show();

    sessionWidgets.append(session);
}

void BearerDialog::createNewSession()
{
    QTreeWidgetItem *item = treeWidget->currentItem();

    createSessionFor(item);
}

void BearerDialog::deleteSession()
{
    SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget());
    if (session) {
        sessionWidgets.removeAll(session);

        delete session;

        if (tabWidget->count() == 0)
            sessionGroup->hide();
    }
}

void BearerDialog::performScan()
{
    scanButton->hide();
    progressBar->show();
    manager.updateConfigurations();
}

<|endoftext|>