<commit_before>#include "blackhole/sink/asynchronous.hpp"

#include <boost/optional/optional.hpp>

#include "blackhole/config/node.hpp"
#include "blackhole/config/option.hpp"
#include "blackhole/registry.hpp"

#include "blackhole/detail/sink/asynchronous.hpp"

#include <cmath>

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

static auto exp2(std::size_t factor) -> std::size_t {
    if (factor > 20) {
        throw std::invalid_argument("factor should fit in [0; 20] range");
    }

    return static_cast<std::size_t>(std::exp2(factor));
}

}  // namespace

class drop_overflow_policy_t : public overflow_policy_t {
    typedef overflow_policy_t::action_t action_t;

public:
    /// Drops on overlow.
    virtual auto overflow() -> action_t {
        return action_t::drop;
    }

    /// Does nothing on wakeup.
    virtual auto wakeup() -> void {}
};

class wait_overflow_policy_t : public overflow_policy_t {
    typedef overflow_policy_t::action_t action_t;

    mutable std::mutex mutex;
    std::condition_variable cv;

public:
    virtual auto overflow() -> action_t {
        std::unique_lock<std::mutex> lock(mutex);
        cv.wait(lock);
        return action_t::retry;
    }

    virtual auto wakeup() -> void {
        cv.notify_one();
    }
};

asynchronous_t::asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor) :
    queue(exp2(factor)),
    stopped(false),
    wrapped(std::move(wrapped)),
    overflow_policy(new wait_overflow_policy_t),
    thread(std::bind(&asynchronous_t::run, this))
{}

asynchronous_t::~asynchronous_t() {
    stopped.store(true);
    thread.join();
}

auto asynchronous_t::emit(const record_t& record, const string_view& message) -> void {
    if (stopped) {
        throw std::logic_error("queue is sealed");
    }

    while (true) {
        const auto enqueued = queue.enqueue_with([&](value_type& value) {
            value = {recordbuf_t(record), message.to_string()};
        });

        if (enqueued) {
            // TODO: underflow_policy->wakeup();
            return;
        } else {
            switch (overflow_policy->overflow()) {
            case overflow_policy_t::action_t::retry:
                continue;
            case overflow_policy_t::action_t::drop:
                return;
            }
        }
    }
}

auto asynchronous_t::run() -> void {
    while (true) {
        value_type result;
        const auto dequeued = queue.dequeue_with([&](value_type& value) {
            result = std::move(value);
        });

        if (dequeued) {
            try {
                wrapped->emit(result.record.into_view(), result.message);
                overflow_policy->wakeup();
            } catch (...) {
                // TODO: exception_policy->process(std::current_exception()); []
            }

        } else {
            ::usleep(1000);
            // TODO: underflow_policy->underflow(); [wait for enqueue, sleep].
        }

        if (stopped && !dequeued) {
            return;
        }
    }
}

}  // namespace sink

auto factory<sink::asynchronous_t>::type() const noexcept -> const char* {
    return "asynchronous";
}

auto factory<sink::asynchronous_t>::from(const config::node_t& config) const -> std::unique_ptr<sink_t> {
    auto factory = registry.sink(*config["sink"]["type"].to_string());
    return std::unique_ptr<sink_t>(new sink::asynchronous_t(factory(*config["sink"].unwrap())));
}

}  // namespace experimental
}  // namespace v1
}  // namespace blackhole
<commit_msg>fix: proper break logic<commit_after>#include "blackhole/sink/asynchronous.hpp"

#include <boost/optional/optional.hpp>

#include "blackhole/config/node.hpp"
#include "blackhole/config/option.hpp"
#include "blackhole/registry.hpp"

#include "blackhole/detail/sink/asynchronous.hpp"

#include <cmath>

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

static auto exp2(std::size_t factor) -> std::size_t {
    if (factor > 20) {
        throw std::invalid_argument("factor should fit in [0; 20] range");
    }

    return static_cast<std::size_t>(std::exp2(factor));
}

}  // namespace

class drop_overflow_policy_t : public overflow_policy_t {
    typedef overflow_policy_t::action_t action_t;

public:
    /// Drops on overlow.
    virtual auto overflow() -> action_t {
        return action_t::drop;
    }

    /// Does nothing on wakeup.
    virtual auto wakeup() -> void {}
};

class wait_overflow_policy_t : public overflow_policy_t {
    typedef overflow_policy_t::action_t action_t;

    mutable std::mutex mutex;
    std::condition_variable cv;

public:
    virtual auto overflow() -> action_t {
        std::unique_lock<std::mutex> lock(mutex);
        cv.wait(lock);
        return action_t::retry;
    }

    virtual auto wakeup() -> void {
        cv.notify_one();
    }
};

asynchronous_t::asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor) :
    queue(exp2(factor)),
    stopped(false),
    wrapped(std::move(wrapped)),
    overflow_policy(new drop_overflow_policy_t),
    thread(std::bind(&asynchronous_t::run, this))
{}

asynchronous_t::~asynchronous_t() {
    stopped.store(true);
    thread.join();
}

auto asynchronous_t::emit(const record_t& record, const string_view& message) -> void {
    if (stopped) {
        throw std::logic_error("queue is sealed");
    }

    while (true) {
        const auto enqueued = queue.enqueue_with([&](value_type& value) {
            value = {recordbuf_t(record), message.to_string()};
        });

        if (enqueued) {
            // TODO: underflow_policy->wakeup();
            return;
        } else {
            switch (overflow_policy->overflow()) {
            case overflow_policy_t::action_t::retry:
                continue;
            case overflow_policy_t::action_t::drop:
                return;
            }
        }
    }
}

auto asynchronous_t::run() -> void {
    while (true) {
        value_type result;
        const auto dequeued = queue.dequeue_with([&](value_type& value) {
            result = std::move(value);
        });

        if (stopped && !dequeued) {
            return;
        }

        if (dequeued) {
            try {
                wrapped->emit(result.record.into_view(), result.message);
                overflow_policy->wakeup();
            } catch (...) {
                throw;
                // TODO: exception_policy->process(std::current_exception()); []
            }

        } else {
            ::usleep(1000);
            // TODO: underflow_policy->underflow(); [wait for enqueue, sleep].
        }
    }
}

}  // namespace sink

auto factory<sink::asynchronous_t>::type() const noexcept -> const char* {
    return "asynchronous";
}

auto factory<sink::asynchronous_t>::from(const config::node_t& config) const -> std::unique_ptr<sink_t> {
    auto factory = registry.sink(*config["sink"]["type"].to_string());
    return std::unique_ptr<sink_t>(new sink::asynchronous_t(factory(*config["sink"].unwrap())));
}

}  // namespace experimental
}  // namespace v1
}  // namespace blackhole
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
3B *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

// primary header
#include "nalReader.h"

// library headers
#include "common/unittest.h"

namespace YamiParser {

class NalReaderTest
    : public ::testing::Test {
};

#define NALREADER_TEST(name) \
    TEST_F(NalReaderTest, name)

NALREADER_TEST(ReadBeyondBoundary)
{
    uint8_t data = 0x55;
    uint32_t u;
    int32_t s;
    NalReader reader(&data, 1);
    EXPECT_EQ(0u, reader.read(1));
    EXPECT_EQ(1u, reader.read(1));
    EXPECT_TRUE(reader.readUe(u));
    EXPECT_EQ(1u, u);
    EXPECT_TRUE(reader.readSe(s));
    EXPECT_EQ(0, s);

    EXPECT_FALSE(reader.end());
    EXPECT_FALSE(reader.read(u, 8));
    EXPECT_TRUE(reader.end());
    EXPECT_FALSE(reader.readUe(u));
    EXPECT_EQ(0u, reader.readUe());
    EXPECT_FALSE(reader.readSe(s));
    EXPECT_EQ(0, reader.readSe());
}

void checkBitreadEmpty(NalReader& reader)
{
    EXPECT_TRUE(reader.end());
    EXPECT_EQ(0u, reader.getPos());
    EXPECT_EQ(0u,
        reader.getRemainingBitsCount());

    uint32_t u;
    int32_t s;
    EXPECT_FALSE(reader.readUe(u));
    EXPECT_FALSE(reader.readSe(s));

    EXPECT_TRUE(reader.end());
}

NALREADER_TEST(NullInit)
{
    uint8_t data = 0;
    NalReader r1(&data, 0);
    checkBitreadEmpty(r1);

    NalReader r2(NULL, 0);
    checkBitreadEmpty(r2);

    EXPECT_DEATH(NalReader r3(NULL, 1), "");
}

} // namespace YamiParser
<commit_msg>unittest: add conner test case for YamiParser::NalReader<commit_after>/*
 * Copyright 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
3B *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

// primary header
#include "nalReader.h"

// library headers
#include "common/unittest.h"

namespace YamiParser {

class NalReaderTest
    : public ::testing::Test {
};

#define NALREADER_TEST(name) \
    TEST_F(NalReaderTest, name)

NALREADER_TEST(ReadBeyondBoundary)
{
    uint8_t data = 0x55;
    uint32_t u;
    int32_t s;
    NalReader reader(&data, 1);
    EXPECT_EQ(0u, reader.read(1));
    EXPECT_EQ(1u, reader.read(1));
    EXPECT_TRUE(reader.readUe(u));
    EXPECT_EQ(1u, u);
    EXPECT_TRUE(reader.readSe(s));
    EXPECT_EQ(0, s);

    EXPECT_FALSE(reader.end());
    EXPECT_FALSE(reader.read(u, 8));
    EXPECT_TRUE(reader.end());
    EXPECT_FALSE(reader.readUe(u));
    EXPECT_EQ(0u, reader.readUe());
    EXPECT_FALSE(reader.readSe(s));
    EXPECT_EQ(0, reader.readSe());
}

void checkBitreadEmpty(NalReader& reader)
{
    EXPECT_TRUE(reader.end());
    EXPECT_EQ(0u, reader.getPos());
    EXPECT_EQ(0u,
        reader.getRemainingBitsCount());

    uint32_t u;
    int32_t s;
    EXPECT_FALSE(reader.readUe(u));
    EXPECT_FALSE(reader.readSe(s));

    EXPECT_TRUE(reader.end());
}

NALREADER_TEST(NullInit)
{
    uint8_t data = 0;
    NalReader r1(&data, 0);
    checkBitreadEmpty(r1);

    NalReader r2(NULL, 0);
    checkBitreadEmpty(r2);

    EXPECT_DEATH(NalReader r3(NULL, 1), "");
}

NALREADER_TEST(GetPosForEPB)
{
    //0x0, 0x0, 0x3, is emulation prevention byte
    const uint8_t data[] = {
        0x0, 0x0, 0x3, 0x0,
        0x0, 0x0, 0x0, 0x0,
        0x1
    };
    NalReader r(data, sizeof(data));
    EXPECT_EQ(0u, r.getPos());

    r.skip(1);
    EXPECT_EQ(1u, r.getPos());

    r.skip(7);
    EXPECT_EQ(8u, r.getPos());

    r.skip(8);
    //we are reach the epb
    EXPECT_EQ(24u, r.getPos());

    r.skip(8);
    EXPECT_EQ(32u, r.getPos());

    r.skip(32);

    uint8_t b;
    EXPECT_TRUE(r.readT(b));
    EXPECT_EQ(1u, b);
}

} // namespace YamiParser
<|endoftext|>


<commit_before><commit_msg>fix: remove earthchain.info from dnsseed as it's defunct<commit_after><|endoftext|>


<commit_before><commit_msg>Re-enable all tests. Disable CheckActiveWindow() instead. The sporadic failures of window_proxy->IsActive() to complete are problematic, but we should keep other coverage while investigating.<commit_after><|endoftext|>


<commit_before>#ifndef CLIENT_OPTS_HPP
#define CLIENT_OPTS_HPP

#include <bits/stdc++.h>
#include <zmqpp/zmqpp.hpp>
#include "constants.hpp"
#include "file.hpp"
#include "json.hpp"

using namespace std;
using namespace zmqpp;
using json = nlohmann::json;

void ListFiles(string &user, socket& s) {
  json req;
  req["type"] = LS_REQ;
  req["user"] = user;

  message m;
  m << req.dump();
  s.send(m);

  message ans;
  s.receive(ans);
  string _res;
  ans >> _res;
  json res = json::parse(_res);

  if (res["res"] == "OK") {
    cout << "Your files are:" << endl;
    for (auto &f : res["data"]) {
      cout << f << endl;
    }
  } else {
    cout << res["res"] << endl;
  }
}

void GetFileFromServer(string &user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  bool first_time = true, finished;
  int cur_pos = 0;
  do {
    json req;
    req["type"] = GET_REQ;
    req["user"] = user;
    req["filename"] = filename;
    req["curPos"] = cur_pos;

    message m;
    m << req.dump();
    s.send(m);

    message ans;
    s.receive(ans);
    string _res;
    ans >> _res;
    json res = json::parse(_res);

    if (res["res"] == "OK") {
      string file = res["file"];
      bool save = SaveFileBase64(filename, file, first_time);
      first_time = false;
      finished = res["finished"];
      cur_pos = res["curPos"];
      cout << "Downloading... " << cur_pos / (double) res["fileSize"] << endl;
      if (!save) {
        cout << "Error saving file" << endl;
      } else {
        cout << "File received succesfully" << endl;
      }
    } else {
      cout << res["res"] << endl;
      break;
    }
  } while (!finished);
}

void SendFileToServer(string& user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  string server_response = "File created!";
  int cur_pos = 0, file_size = FileSize(filename);
  bool finished;
  do {
    json open_file = ReadFileBase64(filename, cur_pos);
    if (open_file["error"] != nullptr) {
      cout << open_file["message"] << endl;
      return;
    }
    string file = open_file["file"];

    json req;
    req["type"] = SEND_REQ;
    req["user"] = user;
    req["filename"] = basename(filename.c_str());
    req["file"] = file;
    req["firstTime"] = (cur_pos == 0);

    cur_pos = open_file["curPos"];
    finished = open_file["finished"];

    message m;
    m << req.dump();
    s.send(m);
    message ans;
    s.receive(ans);
    string _res;
    ans >> _res;
    json res = json::parse(_res);

    if (res["res"] != "OK") {
      server_response = res["res"];
      break;
    } else {
      cout << "Uploading... " << (double) cur_pos / file_size << endl;
    }
  } while (!finished);

  cout << server_response << endl;
}

void RemoveFile(string& user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  json req;
  req["type"] = RM_REQ;
  req["user"] = user;
  req["filename"] = filename;

  message m;
  m << req.dump();
  s.send(m);

  message ans;
  s.receive(ans);
  string _res;
  ans >> _res;
  json res = json::parse(_res);

  if (res["res"] == "OK") {
    cout << "File removed!" << endl;
  } else {
    cout << res["res"] << endl;
  }
}

#endif
<commit_msg>Nice percentages<commit_after>#ifndef CLIENT_OPTS_HPP
#define CLIENT_OPTS_HPP

#include <bits/stdc++.h>
#include <zmqpp/zmqpp.hpp>
#include "constants.hpp"
#include "file.hpp"
#include "json.hpp"

using namespace std;
using namespace zmqpp;
using json = nlohmann::json;

void ListFiles(string &user, socket& s) {
  json req;
  req["type"] = LS_REQ;
  req["user"] = user;

  message m;
  m << req.dump();
  s.send(m);

  message ans;
  s.receive(ans);
  string _res;
  ans >> _res;
  json res = json::parse(_res);

  if (res["res"] == "OK") {
    cout << "Your files are:" << endl;
    for (auto &f : res["data"]) {
      cout << f << endl;
    }
  } else {
    cout << res["res"] << endl;
  }
}

void GetFileFromServer(string &user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  bool first_time = true, finished;
  int cur_pos = 0;
  do {
    json req;
    req["type"] = GET_REQ;
    req["user"] = user;
    req["filename"] = filename;
    req["curPos"] = cur_pos;

    message m;
    m << req.dump();
    s.send(m);

    message ans;
    s.receive(ans);
    string _res;
    ans >> _res;
    json res = json::parse(_res);

    if (res["res"] == "OK") {
      string file = res["file"];
      bool save = SaveFileBase64(filename, file, first_time);
      first_time = false;
      finished = res["finished"];
      cur_pos = res["curPos"];
      if (!save) {
        cout << "Error saving file" << endl;
      } else {
        cout << "Downloading... " << 100 * cur_pos / (double) res["fileSize"] << endl;
      }
    } else {
      cout << res["res"] << endl;
      break;
    }
  } while (!finished);
}

void SendFileToServer(string& user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  string server_response = "File created!";
  int cur_pos = 0, file_size = FileSize(filename);
  bool finished;
  do {
    json open_file = ReadFileBase64(filename, cur_pos);
    if (open_file["error"] != nullptr) {
      cout << open_file["message"] << endl;
      return;
    }
    string file = open_file["file"];

    json req;
    req["type"] = SEND_REQ;
    req["user"] = user;
    req["filename"] = basename(filename.c_str());
    req["file"] = file;
    req["firstTime"] = (cur_pos == 0);

    cur_pos = open_file["curPos"];
    finished = open_file["finished"];

    message m;
    m << req.dump();
    s.send(m);
    message ans;
    s.receive(ans);
    string _res;
    ans >> _res;
    json res = json::parse(_res);

    if (res["res"] != "OK") {
      server_response = res["res"];
      break;
    } else {
      cout << "Uploading... " << 100 * (double) cur_pos / file_size << endl;
    }
  } while (!finished);

  cout << server_response << endl;
}

void RemoveFile(string& user, socket& s) {
  cout << "Enter filename: ";
  string filename;
  cin >> filename;

  json req;
  req["type"] = RM_REQ;
  req["user"] = user;
  req["filename"] = filename;

  message m;
  m << req.dump();
  s.send(m);

  message ans;
  s.receive(ans);
  string _res;
  ans >> _res;
  json res = json::parse(_res);

  if (res["res"] == "OK") {
    cout << "File removed!" << endl;
  } else {
    cout << res["res"] << endl;
  }
}

#endif
<|endoftext|>


<commit_before>#include <fhe/FHEContext.h>
#include <fhe/FHE.h>
#include <fhe/NumbTh.h>
#include <fhe/EncryptedArray.h>
#include <utils/FileUtils.hpp>
#include <utils/timer.hpp>
#include <algebra/NDSS.h>
#include <thread>
#include <atomic>
#include <vector>

#ifdef FHE_THREADS
long WORKER_NR = 8;
#else // ifdef FHE_THREADS
long WORKER_NR = 1;
#endif // ifdef FHE_THREAD
std::vector<MDL::EncVector>encrypt(const MDL::Matrix<long>& data,
                                   const FHEPubKey        & pk,
                                   const EncryptedArray   & ea,
                                   long                     from = 0,
                                   long                     to = 0)
{
    MDL::Timer timer;
    std::vector<MDL::EncVector> ctxts(to - from, pk);
    std::vector<std::thread>    workers;
    std::atomic<size_t> counter(from);

    to = to == 0 ? data.rows() : to;
    timer.start();

    for (long wr = 0; wr < WORKER_NR; wr++) {
        workers.push_back(std::move(std::thread([&data, &ea, &to, &from,
                                                 &counter, &ctxts]() {
            size_t next;

            while ((next = counter.fetch_add(1)) < to) {
                ctxts[next - from].pack(data[next], ea);
            }
        })));
    }

    for (auto && wr : workers) wr.join();
    timer.end();
    printf("Encrypt %ld data with %ld workers costed %f sec\n", to - from,
           WORKER_NR, timer.second());
    return ctxts;
}

MDL::EncVector mean(const std::vector<MDL::EncVector>& ctxts)
{
    std::vector<std::thread>    workers;
    std::vector<MDL::EncVector> partials(WORKER_NR, ctxts[0].getPubKey());
    std::atomic<size_t> counter(WORKER_NR);
    MDL::Timer timer;

    timer.start();

    for (long i = 0; i < WORKER_NR; i++) {
        partials[i] = ctxts[i];
        workers.push_back(std::move(std::thread([&counter, &ctxts]
                                                    (MDL::EncVector& ct) {
            size_t next;

            while ((next = counter.fetch_add(1)) < ctxts.size()) {
                ct += ctxts[next];
            }
        }, std::ref(partials[i]))));
    }

    for (auto && wr : workers) {
        wr.join();
    }

    for (long i = 1; i < WORKER_NR; i++) {
        partials[0] += partials[i];
    }
    timer.end();
    printf("Sum %zd data with %ld workers costed %f sec\n", ctxts.size(),
           WORKER_NR, timer.second());
    return partials[0];
}

MDL::EncVector squareSum(std::vector<MDL::EncVector>& ctxts)
{
    MDL::Timer timer;
    std::atomic<size_t> counter(0);
    std::vector<std::thread> workers;

    timer.start();

    for (long wr = 0; wr < WORKER_NR; wr++) {
        workers.push_back(std::move(std::thread([&ctxts, &counter]() {
            size_t next;

            while ((next = counter.fetch_add(1)) < ctxts.size()) {
                ctxts[next].square();
            }
        })));
    }

    for (auto && wr : workers) wr.join();
    auto sq_sum = mean(ctxts);
    timer.end();
    printf("Square Sum costed %f sec\n", timer.second());
    return sq_sum;
}

MDL::EncVector variance(const MDL::Matrix<long>& data,
                        const EncryptedArray   & ea,
                        const FHEPubKey        & pk)
{
    MDL::EncVector square_sum(pk), sum_square(pk);
    NTL::ZZX   N(data.rows());
    const long BATCH_SIZE = 5000;
    MDL::Timer totalTimer, encTimer, evalTimer;

    totalTimer.start();

    for (long part = 0; part *BATCH_SIZE < data.rows(); part++) {
        long from  = std::min<long>(part * BATCH_SIZE, data.rows());
        long to    = std::min<long>(from + BATCH_SIZE, data.rows());
        encTimer.start();
        auto ctxts = encrypt(data, pk, ea, from, to);
        encTimer.end();
        evalTimer.start();

        if (part > 0) {
            sum_square += mean(ctxts);
            square_sum += squareSum(ctxts);
        } else {
            sum_square = mean(ctxts);
            square_sum = squareSum(ctxts);
        }
        evalTimer.end();
    }

    evalTimer.start();
    sum_square.square();
    square_sum.multByConstant(N);
    square_sum -= sum_square;
    evalTimer.end();
    totalTimer.end();
    printf("Varaice of %zd data with %ld workers used %f(%f/%f)\n",
           data.rows(), WORKER_NR,
           totalTimer.second(),
           encTimer.second(),
           evalTimer.second());
    return square_sum;
}

int main(int argc, char *argv[]) {
    long m, p, r, L;
    ArgMapping argmap;

    argmap.arg("m", m, "m");
    argmap.arg("L", L, "L");
    argmap.arg("p", p, "p");
    argmap.arg("r", r, "r");
    argmap.parse(argc, argv);

    FHEcontext context(m, p, r);
    buildModChain(context, L);
    FHESecKey sk(context);
    sk.GenSecKey(64);
    addSome1DMatrices(sk);
    FHEPubKey pk = sk;

    auto G = context.alMod.getFactorsOverZZ()[0];
    EncryptedArray ea(context, G);

    auto data   = load_csv("adult.data");
    auto result = load_csv("adult_result");

    // auto ctxts  = encrypt(data, pk, ea);

    // {
    //     MDL::Vector<long> ret;
    //     auto summaiton = mean(ctxts);
    //     summaiton.unpack(ret, sk, ea);
    //     std::cout << ret << std::endl;
    //     std::cout << result[0] << std::endl;
    // }

    {
        MDL::Vector<long> ret;
        auto var = variance(data, ea, pk);
        var.unpack(ret, sk, ea);
        std::cout << ret << std::endl;
        std::cout << result[1] << std::endl;
    }
    return 0;
}
<commit_msg>Bug fix!<commit_after>#include <fhe/FHEContext.h>
#include <fhe/FHE.h>
#include <fhe/NumbTh.h>
#include <fhe/EncryptedArray.h>
#include <utils/FileUtils.hpp>
#include <utils/timer.hpp>
#include <algebra/NDSS.h>
#include <thread>
#include <atomic>
#include <vector>

#ifdef FHE_THREADS
long WORKER_NR = 8;
#else // ifdef FHE_THREADS
long WORKER_NR = 1;
#endif // ifdef FHE_THREAD
std::vector<MDL::EncVector>encrypt(const MDL::Matrix<long>& data,
                                   const FHEPubKey        & pk,
                                   const EncryptedArray   & ea,
                                   long                     from = 0,
                                   long                     to = 0)
{
    MDL::Timer timer;
    to = to == 0 ? data.rows() : to;
    std::vector<MDL::EncVector> ctxts(to - from, pk);
    std::vector<std::thread>    workers;
    std::atomic<size_t> counter(from);

    timer.start();

    for (long wr = 0; wr < WORKER_NR; wr++) {
        workers.push_back(std::move(std::thread([&data, &ea, &to, &from,
                                                 &counter, &ctxts]() {
            size_t next;

            while ((next = counter.fetch_add(1)) < to) {
                ctxts[next - from].pack(data[next], ea);
            }
        })));
    }

    for (auto && wr : workers) wr.join();
    timer.end();
    printf("Encrypt %ld data with %ld workers costed %f sec\n", to - from,
           WORKER_NR, timer.second());
    return ctxts;
}

MDL::EncVector mean(const std::vector<MDL::EncVector>& ctxts)
{
    std::vector<std::thread>    workers;
    std::vector<MDL::EncVector> partials(WORKER_NR, ctxts[0].getPubKey());
    std::atomic<size_t> counter(WORKER_NR);
    MDL::Timer timer;

    timer.start();

    for (long i = 0; i < WORKER_NR; i++) {
        partials[i] = ctxts[i];
        workers.push_back(std::move(std::thread([&counter, &ctxts]
                                                    (MDL::EncVector& ct) {
            size_t next;

            while ((next = counter.fetch_add(1)) < ctxts.size()) {
                ct += ctxts[next];
            }
        }, std::ref(partials[i]))));
    }

    for (auto && wr : workers) {
        wr.join();
    }

    for (long i = 1; i < WORKER_NR; i++) {
        partials[0] += partials[i];
    }
    timer.end();
    printf("Sum %zd data with %ld workers costed %f sec\n", ctxts.size(),
           WORKER_NR, timer.second());
    return partials[0];
}

MDL::EncVector squareSum(std::vector<MDL::EncVector>& ctxts)
{
    MDL::Timer timer;
    std::atomic<size_t> counter(0);
    std::vector<std::thread> workers;

    timer.start();

    for (long wr = 0; wr < WORKER_NR; wr++) {
        workers.push_back(std::move(std::thread([&ctxts, &counter]() {
            size_t next;

            while ((next = counter.fetch_add(1)) < ctxts.size()) {
                ctxts[next].square();
            }
        })));
    }

    for (auto && wr : workers) wr.join();
    auto sq_sum = mean(ctxts);
    timer.end();
    printf("Square Sum costed %f sec\n", timer.second());
    return sq_sum;
}

MDL::EncVector variance(const MDL::Matrix<long>& data,
                        const EncryptedArray   & ea,
                        const FHEPubKey        & pk)
{
    MDL::EncVector square_sum(pk), sum_square(pk);
    NTL::ZZX   N(data.rows());
    const long BATCH_SIZE = 5000;
    MDL::Timer totalTimer, encTimer, evalTimer;

    totalTimer.start();

    for (long part = 0; part *BATCH_SIZE < data.rows(); part++) {
        long from  = std::min<long>(part * BATCH_SIZE, data.rows());
        long to    = std::min<long>(from + BATCH_SIZE, data.rows());
        encTimer.start();
        auto ctxts = encrypt(data, pk, ea, from, to);
        encTimer.end();
        evalTimer.start();

        if (part > 0) {
            sum_square += mean(ctxts);
            square_sum += squareSum(ctxts);
        } else {
            sum_square = mean(ctxts);
            square_sum = squareSum(ctxts);
        }
        evalTimer.end();
    }

    evalTimer.start();
    sum_square.square();
    square_sum.multByConstant(N);
    square_sum -= sum_square;
    evalTimer.end();
    totalTimer.end();
    printf("Varaice of %zd data with %ld workers used %f(%f/%f)\n",
           data.rows(), WORKER_NR,
           totalTimer.second(),
           encTimer.second(),
           evalTimer.second());
    return square_sum;
}

int main(int argc, char *argv[]) {
    long m, p, r, L;
    ArgMapping argmap;

    argmap.arg("m", m, "m");
    argmap.arg("L", L, "L");
    argmap.arg("p", p, "p");
    argmap.arg("r", r, "r");
    argmap.parse(argc, argv);

    FHEcontext context(m, p, r);
    buildModChain(context, L);
    FHESecKey sk(context);
    sk.GenSecKey(64);
    addSome1DMatrices(sk);
    FHEPubKey pk = sk;

    auto G = context.alMod.getFactorsOverZZ()[0];
    EncryptedArray ea(context, G);

    auto data   = load_csv("adult.data");
    auto result = load_csv("adult_result");

    // auto ctxts  = encrypt(data, pk, ea);

    // {
    //     MDL::Vector<long> ret;
    //     auto summaiton = mean(ctxts);
    //     summaiton.unpack(ret, sk, ea);
    //     std::cout << ret << std::endl;
    //     std::cout << result[0] << std::endl;
    // }

    {
        MDL::Vector<long> ret;
        auto var = variance(data, ea, pk);
        var.unpack(ret, sk, ea);
        std::cout << ret << std::endl;
        std::cout << result[1] << std::endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>#include "Sparkle.h"

Sparkle::Sparkle (uint16_t columns, uint16_t rows, CRGB * leds, CRGB color, uint16_t emptyness)
: Visualization(columns, rows, leds)
{
  this->emptyness = emptyness;
  this->color = color;
  this->color.maximizeBrightness();
}

void Sparkle::display () {
  uint16_t i = random(this->emptyness);
  while (i < this->rows*this->columns) {
    Serial.print(this->rows);
    Serial.print(' ');
    Serial.print(this->columns);
    Serial.print(' ');
    Serial.println(i);
    this->leds[i] = this->color;
    i = i + random(this->emptyness);
  }
}
<commit_msg>remove debug logging<commit_after>#include "Sparkle.h"

Sparkle::Sparkle (uint16_t columns, uint16_t rows, CRGB * leds, CRGB color, uint16_t emptyness)
: Visualization(columns, rows, leds)
{
  this->emptyness = emptyness;
  this->color = color;
  this->color.maximizeBrightness();
}

void Sparkle::display () {
  uint16_t i = random(this->emptyness);
  while (i < this->rows*this->columns) {
    this->leds[i] = this->color;
    i = i + random(this->emptyness);
  }
}
<|endoftext|>


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

#include "base/base64.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/gfx/codec/png_codec.h"

namespace content {

class RendererOverridesHandlerTest : public ContentBrowserTest,
                                     public DevToolsAgentHostClient {
 protected:
  void SendCommand(const std::string& method,
                   base::DictionaryValue* params) {
    agent_host_->DispatchProtocolMessage(
        DevToolsProtocol::CreateCommand(1, method, params)->Serialize());
    base::MessageLoop::current()->Run();
  }

  bool HasValue(const std::string& path) {
    base::Value* value = 0;
    return result_->Get(path, &value);
  }

  bool HasListItem(const std::string& path_to_list,
                   const std::string& name,
                   const std::string& value) {
    base::ListValue* list;
    if (!result_->GetList(path_to_list, &list))
      return false;

    for (size_t i = 0; i != list->GetSize(); i++) {
      base::DictionaryValue* item;
      if (!list->GetDictionary(i, &item))
        return false;
      std::string id;
      if (!item->GetString(name, &id))
        return false;
      if (id == value)
        return true;
    }
    return false;
  }

  scoped_ptr<base::DictionaryValue> result_;
  scoped_refptr<DevToolsAgentHost> agent_host_;

 private:
  virtual void SetUpOnMainThread() override {
    agent_host_ = DevToolsAgentHost::GetOrCreateFor(shell()->web_contents());
    agent_host_->AttachClient(this);
  }

  virtual void TearDownOnMainThread() override {
    agent_host_->DetachClient();
    agent_host_ = NULL;
  }

  virtual void DispatchProtocolMessage(
      DevToolsAgentHost* agent_host, const std::string& message) override {
    scoped_ptr<base::DictionaryValue> root(
        static_cast<base::DictionaryValue*>(base::JSONReader::Read(message)));
    base::DictionaryValue* result;
    EXPECT_TRUE(root->GetDictionary("result", &result));
    result_.reset(result->DeepCopy());
    base::MessageLoop::current()->QuitNow();
  }

  virtual void AgentHostClosed(
      DevToolsAgentHost* agent_host, bool replaced) override {
    EXPECT_TRUE(false);
  }
};

IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
  base::DictionaryValue* params = new base::DictionaryValue();
  params->SetString("securityOrigin", "http://example.com");
  SendCommand("Page.queryUsageAndQuota", params);

  EXPECT_TRUE(HasValue("quota.persistent"));
  EXPECT_TRUE(HasValue("quota.temporary"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "appcache"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "database"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "indexeddatabase"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "filesystem"));
  EXPECT_TRUE(HasListItem("usage.persistent", "id", "filesystem"));
}

class CaptureScreenshotTest : public RendererOverridesHandlerTest {
 private:
#if !defined(OS_ANDROID)
  virtual void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
  }
#endif
};

// Does not link on Android
#if defined(OS_ANDROID)
#define MAYBE_CaptureScreenshot DISABLED_CaptureScreenshot
#else
#define MAYBE_CaptureScreenshot CaptureScreenshot
#endif
IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, MAYBE_CaptureScreenshot) {
  shell()->LoadURL(GURL("about:blank"));
  EXPECT_TRUE(content::ExecuteScript(
      shell()->web_contents()->GetRenderViewHost(),
      "document.body.style.background = '#123456'"));
  SendCommand("Page.captureScreenshot", new base::DictionaryValue());
  std::string base64;
  EXPECT_TRUE(result_->GetString("data", &base64));
  std::string png;
  EXPECT_TRUE(base::Base64Decode(base64, &png));
  SkBitmap bitmap;
  gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(png.data()),
                        png.size(), &bitmap);
  SkColor color(bitmap.getColor(0, 0));
  EXPECT_TRUE(std::abs(0x12-(int)SkColorGetR(color)) <= 1);
  EXPECT_TRUE(std::abs(0x34-(int)SkColorGetG(color)) <= 1);
  EXPECT_TRUE(std::abs(0x56-(int)SkColorGetB(color)) <= 1);
}

}  // namespace content
<commit_msg>MSAN: Disable flaky CaptureScreenshot test.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/base64.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/gfx/codec/png_codec.h"

namespace content {

class RendererOverridesHandlerTest : public ContentBrowserTest,
                                     public DevToolsAgentHostClient {
 protected:
  void SendCommand(const std::string& method,
                   base::DictionaryValue* params) {
    agent_host_->DispatchProtocolMessage(
        DevToolsProtocol::CreateCommand(1, method, params)->Serialize());
    base::MessageLoop::current()->Run();
  }

  bool HasValue(const std::string& path) {
    base::Value* value = 0;
    return result_->Get(path, &value);
  }

  bool HasListItem(const std::string& path_to_list,
                   const std::string& name,
                   const std::string& value) {
    base::ListValue* list;
    if (!result_->GetList(path_to_list, &list))
      return false;

    for (size_t i = 0; i != list->GetSize(); i++) {
      base::DictionaryValue* item;
      if (!list->GetDictionary(i, &item))
        return false;
      std::string id;
      if (!item->GetString(name, &id))
        return false;
      if (id == value)
        return true;
    }
    return false;
  }

  scoped_ptr<base::DictionaryValue> result_;
  scoped_refptr<DevToolsAgentHost> agent_host_;

 private:
  virtual void SetUpOnMainThread() override {
    agent_host_ = DevToolsAgentHost::GetOrCreateFor(shell()->web_contents());
    agent_host_->AttachClient(this);
  }

  virtual void TearDownOnMainThread() override {
    agent_host_->DetachClient();
    agent_host_ = NULL;
  }

  virtual void DispatchProtocolMessage(
      DevToolsAgentHost* agent_host, const std::string& message) override {
    scoped_ptr<base::DictionaryValue> root(
        static_cast<base::DictionaryValue*>(base::JSONReader::Read(message)));
    base::DictionaryValue* result;
    EXPECT_TRUE(root->GetDictionary("result", &result));
    result_.reset(result->DeepCopy());
    base::MessageLoop::current()->QuitNow();
  }

  virtual void AgentHostClosed(
      DevToolsAgentHost* agent_host, bool replaced) override {
    EXPECT_TRUE(false);
  }
};

IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
  base::DictionaryValue* params = new base::DictionaryValue();
  params->SetString("securityOrigin", "http://example.com");
  SendCommand("Page.queryUsageAndQuota", params);

  EXPECT_TRUE(HasValue("quota.persistent"));
  EXPECT_TRUE(HasValue("quota.temporary"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "appcache"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "database"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "indexeddatabase"));
  EXPECT_TRUE(HasListItem("usage.temporary", "id", "filesystem"));
  EXPECT_TRUE(HasListItem("usage.persistent", "id", "filesystem"));
}

class CaptureScreenshotTest : public RendererOverridesHandlerTest {
 private:
#if !defined(OS_ANDROID)
  virtual void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
  }
#endif
};

// Does not link on Android
#if defined(OS_ANDROID)
#define MAYBE_CaptureScreenshot DISABLED_CaptureScreenshot
#elif defined(MEMORY_SANITIZER)
// Also fails under MSAN. http://crbug.com/423583
#define MAYBE_CaptureScreenshot DISABLED_CaptureScreenshot
#else
#define MAYBE_CaptureScreenshot CaptureScreenshot
#endif
IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, MAYBE_CaptureScreenshot) {
  shell()->LoadURL(GURL("about:blank"));
  EXPECT_TRUE(content::ExecuteScript(
      shell()->web_contents()->GetRenderViewHost(),
      "document.body.style.background = '#123456'"));
  SendCommand("Page.captureScreenshot", new base::DictionaryValue());
  std::string base64;
  EXPECT_TRUE(result_->GetString("data", &base64));
  std::string png;
  EXPECT_TRUE(base::Base64Decode(base64, &png));
  SkBitmap bitmap;
  gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(png.data()),
                        png.size(), &bitmap);
  SkColor color(bitmap.getColor(0, 0));
  EXPECT_TRUE(std::abs(0x12-(int)SkColorGetR(color)) <= 1);
  EXPECT_TRUE(std::abs(0x34-(int)SkColorGetG(color)) <= 1);
  EXPECT_TRUE(std::abs(0x56-(int)SkColorGetB(color)) <= 1);
}

}  // namespace content
<|endoftext|>


<commit_before><commit_msg>Eliminated reference bound to rvalue<commit_after><|endoftext|>


<commit_before>/* Copyright 2019 Andrei Khodko
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "utilities.h"

#include "QsLog.h"

using namespace trikControl;

QImage  Utilities::imageFromBytes(const QVector<int32_t> &array, int width, int height, const QString &format){
	// QImage requires 32-bit aligned scan lines
	// Helper function to convert data
	uchar *formattedData = nullptr;
	auto copyAligned = [&](int perLine){
		if (perLine * height > array.size()) {
			QLOG_WARN() << "imageFromBytes: not enough data";
			return;
		}
		auto scanLineSize = static_cast<int>((static_cast<unsigned>(perLine + 3)) & 0xFFFFFFFC);
		auto dst = formattedData = new uchar[scanLineSize * height];
		for (auto src = array.begin(); src < array.end(); src += perLine) {
			dst = std::copy(src, src + perLine, dst);
			dst += scanLineSize - perLine;
		}
	};

	auto fmt = QImage::Format_Invalid;

	if (!format.compare("rgb32", Qt::CaseInsensitive)) {
		const auto imageSize = width * height;
		fmt = QImage::Format_RGB32;
		if (imageSize <= array.size()) {
			formattedData = new uchar[imageSize * 4];
			auto dstPtr = static_cast<int32_t *>(static_cast<void *>(formattedData));
			std::copy(array.begin(), array.end(), dstPtr);
		}
	} else if (!format.compare("rgb888", Qt::CaseInsensitive)) {
		fmt = QImage::Format_RGB888;
		copyAligned(3 * width);
	} else if (format == "grayscale8") {
		fmt = QImage::Format_Grayscale8;
		copyAligned(1 * width);
	} else {
		QLOG_WARN() << "imageFromBytes: Unsupported format " << format;
	}

	if (!formattedData) {
		return QImage();
	} else {
		static auto cleanUp = [](void *p) { if (p) delete [](static_cast<decltype (formattedData)>(p)); };
		return QImage(formattedData, width, height, fmt, cleanUp, formattedData);
	}
}

static inline int32_t getMedian(uint8_t &a, uint8_t &b, uint8_t &c, uint8_t &d)
{
	if (a > b)
		std::swap(a, b);
	if (c > d)
		std::swap(c, d);
	if (a > c)
		std::swap(a, c);
	if (b > d)
		std::swap(b, d);
	return (static_cast<int32_t>(b) + c) >> 1;
}

QVector<int32_t> Utilities::rescalePhoto(const QVector<uchar> &data)
{
	QVector<int32_t> result;
	result.reserve(data.size() / 3); //Repack RGB88 from 3 x uint8_t into int32_t
	constexpr auto IMAGE_WIDTH = 320;
	constexpr auto IMAGE_HEIGHT = 240;
	if (data.size() >= IMAGE_WIDTH * IMAGE_HEIGHT * 3) {
		for(int row = 0; row < IMAGE_HEIGHT; row += 2) {
			for(int col = 0; col < IMAGE_WIDTH; col += 2) {
				auto row1 = &data[(row * IMAGE_WIDTH + col) * 3];
				auto row2 = row1 + IMAGE_WIDTH * 3;
				auto r1 = row1[0];
				auto g1 = row1[1];
				auto b1 = row1[2];
				auto r2 = row1[3];
				auto g2 = row1[4];
				auto b2 = row1[5];
				auto r3 = row2[0];
				auto g3 = row2[1];
				auto b3 = row2[2];
				auto r4 = row2[3];
				auto g4 = row2[4];
				auto b4 = row2[5];

				result.push_back((getMedian(r1, r2, r3, r4) << 16)
					| (getMedian(g1, g2, g3, g4) << 8)
					| getMedian(b1, b2, b3, b4));
			}
		}
	}

	return result;
}
<commit_msg>Do not crash on extra size<commit_after>/* Copyright 2019 Andrei Khodko
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "utilities.h"

#include "QsLog.h"

using namespace trikControl;

QImage  Utilities::imageFromBytes(const QVector<int32_t> &array, int width, int height, const QString &format){
	// QImage requires 32-bit aligned scan lines
	// Helper function to convert data
	uchar *formattedData = nullptr;
	auto copyAligned = [&](int perLine){
		if (perLine * height > array.size()) {
			QLOG_WARN() << "imageFromBytes: not enough data";
			return;
		}
		auto scanLineSize = static_cast<int>((static_cast<unsigned>(perLine + 3)) & 0xFFFFFFFC);
		auto dst = formattedData = new uchar[scanLineSize * height];
		for (auto src = array.begin(); src < array.end(); src += perLine) {
			dst = std::copy(src, src + perLine, dst);
			dst += scanLineSize - perLine;
		}
	};

	auto fmt = QImage::Format_Invalid;

	if (!format.compare("rgb32", Qt::CaseInsensitive)) {
		const auto imageSize = width * height;
		fmt = QImage::Format_RGB32;
		if (imageSize <= array.size()) {
			formattedData = new uchar[imageSize * 4];
			auto dstPtr = static_cast<int32_t *>(static_cast<void *>(formattedData));
			std::copy(array.begin(), array.begin() + imageSize, dstPtr);
		}
	} else if (!format.compare("rgb888", Qt::CaseInsensitive)) {
		fmt = QImage::Format_RGB888;
		copyAligned(3 * width);
	} else if (format == "grayscale8") {
		fmt = QImage::Format_Grayscale8;
		copyAligned(1 * width);
	} else {
		QLOG_WARN() << "imageFromBytes: Unsupported format " << format;
	}

	if (!formattedData) {
		return QImage();
	} else {
		static auto cleanUp = [](void *p) { if (p) delete [](static_cast<decltype (formattedData)>(p)); };
		return QImage(formattedData, width, height, fmt, cleanUp, formattedData);
	}
}

static inline int32_t getMedian(uint8_t &a, uint8_t &b, uint8_t &c, uint8_t &d)
{
	if (a > b)
		std::swap(a, b);
	if (c > d)
		std::swap(c, d);
	if (a > c)
		std::swap(a, c);
	if (b > d)
		std::swap(b, d);
	return (static_cast<int32_t>(b) + c) >> 1;
}

QVector<int32_t> Utilities::rescalePhoto(const QVector<uchar> &data)
{
	QVector<int32_t> result;
	result.reserve(data.size() / 3); //Repack RGB88 from 3 x uint8_t into int32_t
	constexpr auto IMAGE_WIDTH = 320;
	constexpr auto IMAGE_HEIGHT = 240;
	if (data.size() >= IMAGE_WIDTH * IMAGE_HEIGHT * 3) {
		for(int row = 0; row < IMAGE_HEIGHT; row += 2) {
			for(int col = 0; col < IMAGE_WIDTH; col += 2) {
				auto row1 = &data[(row * IMAGE_WIDTH + col) * 3];
				auto row2 = row1 + IMAGE_WIDTH * 3;
				auto r1 = row1[0];
				auto g1 = row1[1];
				auto b1 = row1[2];
				auto r2 = row1[3];
				auto g2 = row1[4];
				auto b2 = row1[5];
				auto r3 = row2[0];
				auto g3 = row2[1];
				auto b3 = row2[2];
				auto r4 = row2[3];
				auto g4 = row2[4];
				auto b4 = row2[5];

				result.push_back((getMedian(r1, r2, r3, r4) << 16)
					| (getMedian(g1, g2, g3, g4) << 8)
					| getMedian(b1, b2, b3, b4));
			}
		}
	}

	return result;
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_LENNARD_JONES_POTENTIAL
#define MJOLNIR_LENNARD_JONES_POTENTIAL
#include <mjolnir/core/System.hpp>
#include <mjolnir/potential/global/ChainIgnoration.hpp>
#include <vector>
#include <algorithm>
#include <cmath>

namespace mjolnir
{

/*! @brief Lennard-Jones type potential & derivative                       *
 * designed for global force field. so it doesn't have its own parameters. *
 * V(r)  =  4. * epsilon * ((r/sigma)^12 - (r/sigma)^6))                   *
 * dV/dr = 24. * epsilon / r * ((r/sigma)^6 - 2 * (r/sigma)^12)            */
template<typename traitsT, typename ChainIgnoration>
class LennardJonesPotential
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::real_type real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    typedef std::pair<real_type, real_type> parameter_type;

    // topology stuff
    typedef StructureTopology topology_type;
    typedef typename topology_type::chain_id_type        chain_id_type;
    typedef typename topology_type::connection_kind_type connection_kind_type;
    typedef ChainIgnoration chain_ignoration_type;

    // rc = 2.5 * sigma
    constexpr static real_type cutoff_ratio = 2.5;

  public:

    LennardJonesPotential(const std::vector<parameter_type>& radii,
        const std::size_t ex_bonds, const std::size_t ex_contacts)
        : radii_(radii), ignored_chain_(),
          ignored_bonds_(ex_bonds), ignored_contacts_(ex_contacts)
    {}
    LennardJonesPotential(std::vector<parameter_type>&& radii,
        const std::size_t ex_bonds, const std::size_t ex_contacts)
        : radii_(std::move(radii)), ignored_chain_(),
          ignored_bonds_(ex_bonds), ignored_contacts_(ex_contacts)
    {}
    ~LennardJonesPotential() = default;

    real_type potential(const std::size_t i, const std::size_t j,
                        const real_type r) const noexcept
    {
        const real_type sigma = 0.5 * (radii_[i].first + radii_[j].first);
        if(sigma * cutoff_ratio < r){return 0.0;}

        const real_type epsilon = (radii_[i].second == radii_[j].second) ?
           radii_[i].second : std::sqrt(radii_[i].second * radii_[j].second);

        const real_type r1s1   = sigma / r;
        const real_type r3s3   = r1s1 * r1s1 * r1s1;
        const real_type r6s6   = r3s3 * r3s3;
        const real_type r12s12 = r6s6 * r6s6;
        return 4.0 * epsilon * (r12s12 - r6s6);
    }

    real_type derivative(const std::size_t i, const std::size_t j,
                         const real_type r) const noexcept
    {
        const real_type sigma = 0.5 * (radii_[i].first + radii_[j].first);
        if(sigma * cutoff_ratio < r){return 0.0;}

        const real_type epsilon = (radii_[i].second == radii_[j].second) ?
           radii_[i].second : std::sqrt(radii_[i].second * radii_[j].second);

        const real_type r1s1   = sigma / r;
        const real_type r3s3   = r1s1 * r1s1 * r1s1;
        const real_type r6s6   = r3s3 * r3s3;
        const real_type r12s12 = r6s6 * r6s6;
        return 24.0 * epsilon * (r6s6 - 2.0 * r12s12) / r;
    }

    real_type max_cutoff_length() const noexcept
    {
        const real_type max_sigma = std::max_element(
            this->radii_.cbegin(), this->radii_.cend(),
            [](const parameter_type& lhs, const parameter_type& rhs) noexcept {
                return lhs.first < rhs.first;
            })->first;
        return max_sigma * cutoff_ratio;
    }

    // nothing to do when system parameters change.
    void update(const System<traitsT>& sys) const noexcept {return;}

    // e.g. `3` means ignore particles connected within 3 "bond"s
    std::size_t ignored_bonds()    const noexcept {return ignored_bonds_;}
    std::size_t ignored_contacts() const noexcept {return ignored_contacts_;}

    bool is_ignored_chain(
            const chain_id_type& i, const chain_id_type& j) const noexcept
    {
        return ignored_chain_.is_ignored(i, j);
    }

    std::string name() const noexcept {return "LennardJones";}

    // access to the parameters...
    std::vector<parameter_type>&       radii()       noexcept {return radii_;}
    std::vector<parameter_type> const& radii() const noexcept {return radii_;}

  private:

    std::vector<parameter_type> radii_;

    chain_ignoration_type ignored_chain_;
    std::size_t ignored_bonds_;
    std::size_t ignored_contacts_;
};
template<typename traitsT, typename ignoreT>
constexpr typename LennardJonesPotential<traitsT, ignoreT>::real_type
LennardJonesPotential<traitsT, ignoreT>::cutoff_ratio;

} // mjolnir
#endif /* MJOLNIR_LENNARD_JONES_POTENTIAL */
<commit_msg>nit: add comment for L-J::parameter_type<commit_after>#ifndef MJOLNIR_LENNARD_JONES_POTENTIAL
#define MJOLNIR_LENNARD_JONES_POTENTIAL
#include <mjolnir/core/System.hpp>
#include <mjolnir/potential/global/ChainIgnoration.hpp>
#include <vector>
#include <algorithm>
#include <cmath>

namespace mjolnir
{

/*! @brief Lennard-Jones type potential & derivative                       *
 * designed for global force field. so it doesn't have its own parameters. *
 * V(r)  =  4. * epsilon * ((r/sigma)^12 - (r/sigma)^6))                   *
 * dV/dr = 24. * epsilon / r * ((r/sigma)^6 - 2 * (r/sigma)^12)            */
template<typename traitsT, typename ChainIgnoration>
class LennardJonesPotential
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::real_type real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    // pair of {sigma, epsilon}
    typedef std::pair<real_type, real_type> parameter_type;

    // topology stuff
    typedef StructureTopology topology_type;
    typedef typename topology_type::chain_id_type        chain_id_type;
    typedef typename topology_type::connection_kind_type connection_kind_type;
    typedef ChainIgnoration chain_ignoration_type;

    // rc = 2.5 * sigma
    constexpr static real_type cutoff_ratio = 2.5;

  public:

    LennardJonesPotential(const std::vector<parameter_type>& radii,
        const std::size_t ex_bonds, const std::size_t ex_contacts)
        : radii_(radii), ignored_chain_(),
          ignored_bonds_(ex_bonds), ignored_contacts_(ex_contacts)
    {}
    LennardJonesPotential(std::vector<parameter_type>&& radii,
        const std::size_t ex_bonds, const std::size_t ex_contacts)
        : radii_(std::move(radii)), ignored_chain_(),
          ignored_bonds_(ex_bonds), ignored_contacts_(ex_contacts)
    {}
    ~LennardJonesPotential() = default;

    real_type potential(const std::size_t i, const std::size_t j,
                        const real_type r) const noexcept
    {
        const real_type sigma = 0.5 * (radii_[i].first + radii_[j].first);
        if(sigma * cutoff_ratio < r){return 0.0;}

        const real_type epsilon = (radii_[i].second == radii_[j].second) ?
           radii_[i].second : std::sqrt(radii_[i].second * radii_[j].second);

        const real_type r1s1   = sigma / r;
        const real_type r3s3   = r1s1 * r1s1 * r1s1;
        const real_type r6s6   = r3s3 * r3s3;
        const real_type r12s12 = r6s6 * r6s6;
        return 4.0 * epsilon * (r12s12 - r6s6);
    }

    real_type derivative(const std::size_t i, const std::size_t j,
                         const real_type r) const noexcept
    {
        const real_type sigma = 0.5 * (radii_[i].first + radii_[j].first);
        if(sigma * cutoff_ratio < r){return 0.0;}

        const real_type epsilon = (radii_[i].second == radii_[j].second) ?
           radii_[i].second : std::sqrt(radii_[i].second * radii_[j].second);

        const real_type r1s1   = sigma / r;
        const real_type r3s3   = r1s1 * r1s1 * r1s1;
        const real_type r6s6   = r3s3 * r3s3;
        const real_type r12s12 = r6s6 * r6s6;
        return 24.0 * epsilon * (r6s6 - 2.0 * r12s12) / r;
    }

    real_type max_cutoff_length() const noexcept
    {
        const real_type max_sigma = std::max_element(
            this->radii_.cbegin(), this->radii_.cend(),
            [](const parameter_type& lhs, const parameter_type& rhs) noexcept {
                return lhs.first < rhs.first;
            })->first;
        return max_sigma * cutoff_ratio;
    }

    // nothing to do when system parameters change.
    void update(const System<traitsT>& sys) const noexcept {return;}

    // e.g. `3` means ignore particles connected within 3 "bond"s
    std::size_t ignored_bonds()    const noexcept {return ignored_bonds_;}
    std::size_t ignored_contacts() const noexcept {return ignored_contacts_;}

    bool is_ignored_chain(
            const chain_id_type& i, const chain_id_type& j) const noexcept
    {
        return ignored_chain_.is_ignored(i, j);
    }

    std::string name() const noexcept {return "LennardJones";}

    // access to the parameters...
    std::vector<parameter_type>&       radii()       noexcept {return radii_;}
    std::vector<parameter_type> const& radii() const noexcept {return radii_;}

  private:

    std::vector<parameter_type> radii_;

    chain_ignoration_type ignored_chain_;
    std::size_t ignored_bonds_;
    std::size_t ignored_contacts_;
};
template<typename traitsT, typename ignoreT>
constexpr typename LennardJonesPotential<traitsT, ignoreT>::real_type
LennardJonesPotential<traitsT, ignoreT>::cutoff_ratio;

} // mjolnir
#endif /* MJOLNIR_LENNARD_JONES_POTENTIAL */
<|endoftext|>


<commit_before>/* Copyright 2014-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */
#include "watchman.h"
// some versions of dbghelp.h do: typedef enum {}; with no typedef name
#pragma warning(disable: 4091)
#include <Dbghelp.h>
#include <mutex>

static std::once_flag sym_init_once;
static HANDLE proc;
// 4k for a symbol name? Demangled symbols are pretty huge
static constexpr size_t kMaxSymbolLen = 4096;

static void sym_init(void) {
  proc = GetCurrentProcess();
  SymInitialize(proc, NULL, TRUE);
  SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_FAIL_CRITICAL_ERRORS|
      SYMOPT_NO_PROMPTS|SYMOPT_UNDNAME);
}

size_t backtrace(void **frames, size_t n_frames) {
  std::call_once(sym_init_once, sym_init);
  // Skip the first three frames; they're always going to show
  // w_log, log_stack_trace and backtrace
  return CaptureStackBackTrace(3, (DWORD)n_frames, frames, NULL);
}

char **backtrace_symbols(void **array, size_t n_frames) {
  std::vector<std::string> arr;
  size_t i;
  union {
    SYMBOL_INFO info;
    char buf[kMaxSymbolLen];
  } sym;
  IMAGEHLP_LINE64 line;
  // How much space we need to hold the final argv style
  // array for the results
  size_t totalSize = 0;

  std::call_once(sym_init_once, sym_init);

  sym.info = SYMBOL_INFO();
  sym.info.MaxNameLen = sizeof(sym) - sizeof(sym.info);
  sym.info.SizeOfStruct = sizeof(sym.info);

  line.SizeOfStruct = sizeof(line);

  for (i = 0; i < n_frames; i++) {
    char str[kMaxSymbolLen + 128];
    DWORD64 addr = (DWORD64)(intptr_t)array[i];
    DWORD displacement;

    if (!SymFromAddr(proc, addr, 0, &sym.info)) {
      snprintf(
          sym.info.Name,
          sizeof(sym.buf),
          "<failed to resolve symbol: %s>",
          std::system_category().message(GetLastError()).c_str());
    }

    if (SymGetLineFromAddr64(proc, addr, &displacement, &line)) {
      snprintf(str, sizeof(str), "#%" PRIsize_t " %p %s %s:%u", i,
        array[i], sym.info.Name, line.FileName, line.LineNumber);

    } else {
      snprintf(str, sizeof(str), "#%" PRIsize_t " %p %s", i,
        array[i], sym.info.Name);
    }

    arr.emplace_back(str);
    // One pointer, the string content and the trailing NUL byte
    totalSize += sizeof(char*) + arr.back().size() + 1;
  }

  auto strings = (char**)malloc(totalSize + sizeof(char*));
  if (!strings) {
    return nullptr;
  }

  auto buf = (char*)(strings + arr.size() + 1);
  for (i = 0; i < arr.size(); ++i) {
    strings[i] = buf;
    memcpy(buf, arr[i].c_str(), arr[i].size() + 1);
    buf += arr[i].size() + 1;
  }
  strings[i] = nullptr;

  return strings;
}

size_t backtrace_from_exception(
    LPEXCEPTION_POINTERS exception,
    void** frames,
    size_t n_frames) {
  std::call_once(sym_init_once, sym_init);

  auto context = exception->ContextRecord;
  auto thread = GetCurrentThread();
  STACKFRAME64 frame;
  DWORD image;
  size_t i = 0;
#ifdef _M_IX86
  image = IMAGE_FILE_MACHINE_I386;
  frame.AddrPC.Offset = context->Eip;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->Ebp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->Esp;
  frame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
  image = IMAGE_FILE_MACHINE_AMD64;
  frame.AddrPC.Offset = context->Rip;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->Rsp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->Rsp;
  frame.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
  image = IMAGE_FILE_MACHINE_IA64;
  frame.AddrPC.Offset = context->StIIP;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->IntSp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrBStore.Offset = context->RsBSP;
  frame.AddrBStore.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->IntSp;
  frame.AddrStack.Mode = AddrModeFlat;
#else
  return 0; // No stack trace for you!
#endif
  while (i < n_frames && StackWalk64(
                             image,
                             proc,
                             thread,
                             &frame,
                             context,
                             nullptr,
                             nullptr,
                             nullptr,
                             nullptr)) {
    frames[i++] = (void*)frame.AddrPC.Offset;
  }
  return i;
}
<commit_msg>fix backtrace.cpp compilation on vs 2017<commit_after>/* Copyright 2014-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */
#include "watchman.h"
// some versions of dbghelp.h do: typedef enum {}; with no typedef name
#pragma warning(disable: 4091)

// dbghelp.h relies on these symbols being defined by its user
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif

#include <Dbghelp.h>
#include <mutex>

static std::once_flag sym_init_once;
static HANDLE proc;
// 4k for a symbol name? Demangled symbols are pretty huge
static constexpr size_t kMaxSymbolLen = 4096;

static void sym_init(void) {
  proc = GetCurrentProcess();
  SymInitialize(proc, NULL, TRUE);
  SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_FAIL_CRITICAL_ERRORS|
      SYMOPT_NO_PROMPTS|SYMOPT_UNDNAME);
}

size_t backtrace(void **frames, size_t n_frames) {
  std::call_once(sym_init_once, sym_init);
  // Skip the first three frames; they're always going to show
  // w_log, log_stack_trace and backtrace
  return CaptureStackBackTrace(3, (DWORD)n_frames, frames, NULL);
}

char **backtrace_symbols(void **array, size_t n_frames) {
  std::vector<std::string> arr;
  size_t i;
  union {
    SYMBOL_INFO info;
    char buf[kMaxSymbolLen];
  } sym;
  IMAGEHLP_LINE64 line;
  // How much space we need to hold the final argv style
  // array for the results
  size_t totalSize = 0;

  std::call_once(sym_init_once, sym_init);

  sym.info = SYMBOL_INFO();
  sym.info.MaxNameLen = sizeof(sym) - sizeof(sym.info);
  sym.info.SizeOfStruct = sizeof(sym.info);

  line.SizeOfStruct = sizeof(line);

  for (i = 0; i < n_frames; i++) {
    char str[kMaxSymbolLen + 128];
    DWORD64 addr = (DWORD64)(intptr_t)array[i];
    DWORD displacement;

    if (!SymFromAddr(proc, addr, 0, &sym.info)) {
      snprintf(
          sym.info.Name,
          sizeof(sym.buf),
          "<failed to resolve symbol: %s>",
          std::system_category().message(GetLastError()).c_str());
    }

    if (SymGetLineFromAddr64(proc, addr, &displacement, &line)) {
      snprintf(str, sizeof(str), "#%" PRIsize_t " %p %s %s:%u", i,
        array[i], sym.info.Name, line.FileName, line.LineNumber);

    } else {
      snprintf(str, sizeof(str), "#%" PRIsize_t " %p %s", i,
        array[i], sym.info.Name);
    }

    arr.emplace_back(str);
    // One pointer, the string content and the trailing NUL byte
    totalSize += sizeof(char*) + arr.back().size() + 1;
  }

  auto strings = (char**)malloc(totalSize + sizeof(char*));
  if (!strings) {
    return nullptr;
  }

  auto buf = (char*)(strings + arr.size() + 1);
  for (i = 0; i < arr.size(); ++i) {
    strings[i] = buf;
    memcpy(buf, arr[i].c_str(), arr[i].size() + 1);
    buf += arr[i].size() + 1;
  }
  strings[i] = nullptr;

  return strings;
}

size_t backtrace_from_exception(
    LPEXCEPTION_POINTERS exception,
    void** frames,
    size_t n_frames) {
  std::call_once(sym_init_once, sym_init);

  auto context = exception->ContextRecord;
  auto thread = GetCurrentThread();
  STACKFRAME64 frame;
  DWORD image;
  size_t i = 0;
#ifdef _M_IX86
  image = IMAGE_FILE_MACHINE_I386;
  frame.AddrPC.Offset = context->Eip;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->Ebp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->Esp;
  frame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
  image = IMAGE_FILE_MACHINE_AMD64;
  frame.AddrPC.Offset = context->Rip;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->Rsp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->Rsp;
  frame.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
  image = IMAGE_FILE_MACHINE_IA64;
  frame.AddrPC.Offset = context->StIIP;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context->IntSp;
  frame.AddrFrame.Mode = AddrModeFlat;
  frame.AddrBStore.Offset = context->RsBSP;
  frame.AddrBStore.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context->IntSp;
  frame.AddrStack.Mode = AddrModeFlat;
#else
  return 0; // No stack trace for you!
#endif
  while (i < n_frames && StackWalk64(
                             image,
                             proc,
                             thread,
                             &frame,
                             context,
                             nullptr,
                             nullptr,
                             nullptr,
                             nullptr)) {
    frames[i++] = (void*)frame.AddrPC.Offset;
  }
  return i;
}
<|endoftext|>


<commit_before>#include <memory>

#define IMPLEMENT_ME std::terminate();

namespace archie {
namespace utils {
  namespace containers {
    template <typename Tp, typename Alloc = std::allocator<Tp>>
    struct dynamic_array {
      using allocator_type = Alloc;
      using pointer = typename allocator_type::pointer;
      using const_pointer = typename allocator_type::const_pointer;
      using value_type = typename allocator_type::value_type;
      using reference = typename allocator_type::reference;
      using const_reference = typename allocator_type::const_reference;
      using size_type = typename allocator_type::size_type;
      using difference_type = typename allocator_type::difference_type;

      using iterator = __gnu_cxx::__normal_iterator<pointer, dynamic_array>;
      using const_iterator = __gnu_cxx::__normal_iterator<const_pointer, dynamic_array>;
      using reverse_iterator = std::reverse_iterator<iterator>;
      using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    private:
      using tp_alloc = typename allocator_type::template rebind<Tp>::other;
      struct impl : private tp_alloc {
        using tp_alloc::allocate;
        using tp_alloc::deallocate;
        using tp_alloc::construct;
        using tp_alloc::destroy;

        pointer start_ = nullptr;
        pointer finish_ = nullptr;
        pointer end_of_storage_ = nullptr;

        impl() noexcept = default;

        explicit impl(tp_alloc const& a) noexcept : tp_alloc(a),
                                                    start_(nullptr),
                                                    finish_(nullptr),
                                                    end_of_storage_(nullptr) {}

        void create_storage(size_type n) {
          if (n != size_type(end_of_storage_ - start_)) {
            start_ = (n != 0u) ? allocate(n) : nullptr;
            finish_ = start_;
            end_of_storage_ = start_ + n;
          }
        }

        void destroy_storage() noexcept { deallocate(start_, end_of_storage_ - start_); }

        tp_alloc& get_allocator() noexcept { return static_cast<tp_alloc&>(*this); }

        tp_alloc const& get_allocator() const noexcept {
          return static_cast<tp_alloc const&>(*this);
        }

        void swap(impl& x) noexcept {
          std::swap(start_, x.start_);
          std::swap(finish_, x.finish_);
          std::swap(end_of_storage_, x.end_of_storage_);
          std::swap(get_allocator(), x.get_allocator());
        }
      };

      impl impl_;

    public:
      dynamic_array() = default;

      explicit dynamic_array(size_type n) { impl_.create_storage(n); }

      explicit dynamic_array(allocator_type const& a) : impl_(a) {}

      dynamic_array(size_type n, allocator_type const& a) : impl_(a) { impl_.create_storage(n); }

      dynamic_array(dynamic_array&& x) { impl_.swap(x.impl_); }

      dynamic_array& operator=(dynamic_array&&) = default;

      dynamic_array(dynamic_array const&) { IMPLEMENT_ME }

      dynamic_array& operator=(dynamic_array const&) {
        IMPLEMENT_ME
        return *this;
      }

      dynamic_array(std::initializer_list<value_type>) { IMPLEMENT_ME }

      dynamic_array& operator=(std::initializer_list<value_type>) {
        IMPLEMENT_ME
        return *this;
      }

      template <typename InputIterator>
      dynamic_array(InputIterator, InputIterator) /*noexcept if copy ctor */ {
        IMPLEMENT_ME
      }

      ~dynamic_array() noexcept {
        clear();
        impl_.destroy_storage();
      }

      size_type capacity() const noexcept {
        return size_type(impl_.end_of_storage_ - impl_.start_);
      }

      size_type size() const noexcept { return size_type(impl_.finish_ - impl_.start_); }

      bool empty() const noexcept { return cbegin() == cend(); }

      bool full() const noexcept { return impl_.finish_ == impl_.end_of_storage_; }

      template <typename... Args>
      void emplace_back(Args&&... args) /*noexcept if ctor */ {
        impl_.construct(impl_.finish_, std::forward<Args>(args)...);
        ++impl_.finish_;
      }

      void push_back(const_reference x) /*noexcept if copy ctor */ { emplace_back(x); }

      void push_back(value_type&& x) /*noexcept if move ctor */ { emplace_back(std::move(x)); }

      void pop_back() noexcept { impl_.destroy(--impl_.finish_); }

      void erase(iterator pos) /* noexcept if move assign */ {
        auto current = pos;
        ++pos;
        for (; pos != end(); ++pos, ++current) { *current = std::move(*pos); }
        pop_back();
      }

      void clear() noexcept {
        while (!empty()) pop_back();
      }

      const_reference operator[](size_type n) const noexcept { return *(impl_.start_ + n); }

      reference operator[](size_type n) noexcept { return *(impl_.start_ + n); }

      iterator begin() noexcept { return iterator(impl_.start_); }

      iterator end() noexcept { return iterator(impl_.finish_); }

      const_iterator cbegin() const noexcept { return const_iterator(impl_.start_); }

      const_iterator begin() const noexcept { return cbegin(); }

      const_iterator cend() const noexcept { return const_iterator(impl_.finish_); }

      const_iterator end() const noexcept { return cend(); }

      pointer data() noexcept { return impl_.start_; }

      const_pointer data() const noexcept { return impl_.start_; }

      pointer release() noexcept {
        auto ptr = data();
        impl_.start_ = nullptr;
        impl_.finish_ = nullptr;
        impl_.end_of_storage_ = nullptr;
        return ptr;
      }

      allocator_type& get_allocator() noexcept {
        static_cast<allocator_type&>(impl_.get_allocator());
      }

      allocator_type const& get_allocator() const noexcept {
        static_cast<allocator_type const&>(impl_.get_allocator());
      }
    };
  }
}
}

#include <archie/utils/test.h>
#include <memory>
namespace cont = archie::utils::containers;

struct resource {
  resource(int i) : handle(new int(i)) {}
  resource(resource const& x) : handle(new int(*(x.handle))) {}
  resource(resource&& x) noexcept : handle(x.handle) { x.handle = nullptr; }
  resource& operator=(resource const& x) {
    if (handle == nullptr)
      handle = new int(*x.handle);
    else
      *handle = *(x.handle);
    return *this;
  }
  resource& operator=(resource&& x) noexcept {
    if (handle) delete handle;
    handle = x.handle;
    x.handle = nullptr;
    return *this;
  }
  ~resource() noexcept {
    if (handle) delete handle;
  }
  int* handle = nullptr;
  friend bool operator==(resource const& r, int i) noexcept { return *r.handle == i; }
  friend bool operator==(int i, resource const& r) noexcept { return r == i; }
  friend bool operator!=(int i, resource const& r) noexcept { return !(r == i); }
  friend bool operator!=(resource const& r, int i) noexcept { return !(r == i); }
};

using darray = cont::dynamic_array<resource>;

void canDefaultConstructDynamicArray() {
  darray da;
  EXPECT_EQ(0u, da.capacity());
  EXPECT_TRUE(da.empty());
}

void canCreateDynamicArrayWithGivenCapacity() {
  darray da1(1);
  darray da3(3);
  EXPECT_EQ(1u, da1.capacity());
  EXPECT_TRUE(da1.empty());

  EXPECT_EQ(3u, da3.capacity());
  EXPECT_TRUE(da3.empty());
}

void canMoveConstructDynamicArray() {
  darray da1(1);
  {
    EXPECT_EQ(1u, da1.capacity());
    EXPECT_TRUE(da1.empty());
  }

  darray da(std::move(da1));
  EXPECT_EQ(0u, da1.capacity());
  EXPECT_TRUE(da1.empty());
  EXPECT_EQ(1u, da.capacity());
  EXPECT_TRUE(da.empty());
}

void canEmplaceBackElement() {
  darray da(1);
  {
    EXPECT_EQ(1u, da.capacity());
    EXPECT_EQ(0u, da.size());
    EXPECT_TRUE(da.empty());
  }

  da.emplace_back(7);
  EXPECT_EQ(1u, da.capacity());
  EXPECT_EQ(1u, da.size());
  EXPECT_FALSE(da.empty());
  EXPECT_EQ(7, da[0]);
}

void canPopBackElement() {
  darray da(1);
  {
    EXPECT_EQ(1u, da.capacity());
    da.emplace_back(7);
    EXPECT_EQ(1u, da.capacity());
    EXPECT_EQ(1u, da.size());
    EXPECT_FALSE(da.empty());
  }

  da.pop_back();
  EXPECT_EQ(1u, da.capacity());
  EXPECT_EQ(0u, da.size());
  EXPECT_TRUE(da.empty());
}

void canEraseElement() {
  darray da(3);
  {
    da.emplace_back(7);
    da.emplace_back(11);
    da.emplace_back(13);
    EXPECT_EQ(3u, da.size());
    EXPECT_TRUE(da.full());
    EXPECT_EQ(7, da[0]);
    EXPECT_EQ(11, da[1]);
    EXPECT_EQ(13, da[2]);
  }

  da.erase(da.begin());
  {
    EXPECT_EQ(2u, da.size());
    EXPECT_FALSE(da.full());
    EXPECT_EQ(11, da[0]);
    EXPECT_EQ(13, da[1]);
  }

  da.erase(da.begin() + 1);
  {
    EXPECT_EQ(1u, da.size());
    EXPECT_EQ(11, da[0]);
  }

  da.erase(da.begin());
  EXPECT_EQ(3u, da.capacity());
  EXPECT_TRUE(da.empty());
}

int main() {
  canDefaultConstructDynamicArray();
  canCreateDynamicArrayWithGivenCapacity();
  canMoveConstructDynamicArray();
  canEmplaceBackElement();
  canPopBackElement();
  canEraseElement();
  return 0;
}
<commit_msg>change way of releasing<commit_after>#include <memory>
#include <tuple>

#define IMPLEMENT_ME std::terminate();

namespace archie {
namespace utils {
  namespace containers {
    template <typename Tp, typename Alloc = std::allocator<Tp>>
    struct dynamic_array {
      using allocator_type = Alloc;
      using pointer = typename allocator_type::pointer;
      using const_pointer = typename allocator_type::const_pointer;
      using value_type = typename allocator_type::value_type;
      using reference = typename allocator_type::reference;
      using const_reference = typename allocator_type::const_reference;
      using size_type = typename allocator_type::size_type;
      using difference_type = typename allocator_type::difference_type;

      using iterator = __gnu_cxx::__normal_iterator<pointer, dynamic_array>;
      using const_iterator = __gnu_cxx::__normal_iterator<const_pointer, dynamic_array>;
      using reverse_iterator = std::reverse_iterator<iterator>;
      using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    private:
      using tp_alloc = typename allocator_type::template rebind<Tp>::other;
      struct impl : private tp_alloc {
        using tp_alloc::allocate;
        using tp_alloc::deallocate;
        using tp_alloc::construct;
        using tp_alloc::destroy;

        pointer start_ = nullptr;
        pointer finish_ = nullptr;
        pointer end_of_storage_ = nullptr;

        impl() noexcept = default;

        explicit impl(tp_alloc const& a) noexcept : tp_alloc(a),
                                                    start_(nullptr),
                                                    finish_(nullptr),
                                                    end_of_storage_(nullptr) {}

        void create_storage(size_type n) {
          if (n != size_type(end_of_storage_ - start_)) {
            start_ = (n != 0u) ? allocate(n) : nullptr;
            finish_ = start_;
            end_of_storage_ = start_ + n;
          }
        }

        void destroy_storage() noexcept { deallocate(start_, end_of_storage_ - start_); }

        tp_alloc& get_allocator() noexcept { return static_cast<tp_alloc&>(*this); }

        tp_alloc const& get_allocator() const noexcept {
          return static_cast<tp_alloc const&>(*this);
        }

        void swap(impl& x) noexcept {
          std::swap(start_, x.start_);
          std::swap(finish_, x.finish_);
          std::swap(end_of_storage_, x.end_of_storage_);
          std::swap(get_allocator(), x.get_allocator());
        }
      };

      impl impl_;

    public:
      dynamic_array() = default;

      explicit dynamic_array(size_type n) { impl_.create_storage(n); }

      explicit dynamic_array(allocator_type const& a) : impl_(a) {}

      dynamic_array(size_type n, allocator_type const& a) : impl_(a) { impl_.create_storage(n); }

      dynamic_array(dynamic_array&& x) { impl_.swap(x.impl_); }

      dynamic_array& operator=(dynamic_array&&) = default;

      dynamic_array(dynamic_array const&) { IMPLEMENT_ME }

      dynamic_array& operator=(dynamic_array const&) {
        IMPLEMENT_ME
        return *this;
      }

      dynamic_array(std::initializer_list<value_type>) { IMPLEMENT_ME }

      dynamic_array& operator=(std::initializer_list<value_type>) {
        IMPLEMENT_ME
        return *this;
      }

      template <typename InputIterator>
      dynamic_array(InputIterator, InputIterator) /*noexcept if copy ctor */ {
        IMPLEMENT_ME
      }

      ~dynamic_array() noexcept {
        clear();
        if (capacity() != 0u) impl_.destroy_storage();
      }

      size_type capacity() const noexcept {
        return size_type(impl_.end_of_storage_ - impl_.start_);
      }

      size_type size() const noexcept { return size_type(impl_.finish_ - impl_.start_); }

      bool empty() const noexcept { return cbegin() == cend(); }

      bool full() const noexcept { return impl_.finish_ == impl_.end_of_storage_; }

      template <typename... Args>
      void emplace_back(Args&&... args) /*noexcept if ctor */ {
        impl_.construct(impl_.finish_, std::forward<Args>(args)...);
        ++impl_.finish_;
      }

      void push_back(const_reference x) /*noexcept if copy ctor */ { emplace_back(x); }

      void push_back(value_type&& x) /*noexcept if move ctor */ { emplace_back(std::move(x)); }

      void pop_back() noexcept { impl_.destroy(--impl_.finish_); }

      void erase(iterator pos) /* noexcept if move assign */ {
        std::move(pos + 1, end(), pos);
        pop_back();
      }

      void clear() noexcept {
        while (!empty()) pop_back();
      }

      const_reference operator[](size_type n) const noexcept { return *(impl_.start_ + n); }

      reference operator[](size_type n) noexcept { return *(impl_.start_ + n); }

      iterator begin() noexcept { return iterator(impl_.start_); }

      iterator end() noexcept { return iterator(impl_.finish_); }

      const_iterator cbegin() const noexcept { return const_iterator(impl_.start_); }

      const_iterator begin() const noexcept { return cbegin(); }

      const_iterator cend() const noexcept { return const_iterator(impl_.finish_); }

      const_iterator end() const noexcept { return cend(); }

      pointer data() noexcept { return impl_.start_; }

      const_pointer data() const noexcept { return impl_.start_; }

      std::tuple<pointer, pointer, pointer> release() noexcept {
        auto ret = std::make_tuple(impl_.start_, impl_.finish_, impl_.end_of_storage_);
        impl_.start_ = nullptr;
        impl_.finish_ = nullptr;
        impl_.end_of_storage_ = nullptr;
        return ret;
      }

      allocator_type& get_allocator() noexcept {
        return static_cast<allocator_type&>(impl_.get_allocator());
      }

      allocator_type const& get_allocator() const noexcept {
        return static_cast<allocator_type const&>(impl_.get_allocator());
      }
    };
  }
}
}

#include <archie/utils/test.h>
#include <memory>
namespace cont = archie::utils::containers;

struct resource {
  resource(int i) : handle(new int(i)) {}
  resource(resource const& x) : handle(new int(*(x.handle))) {}
  resource(resource&& x) noexcept : handle(x.handle) { x.handle = nullptr; }
  resource& operator=(resource const& x) {
    if (handle == nullptr)
      handle = new int(*x.handle);
    else
      *handle = *(x.handle);
    return *this;
  }
  resource& operator=(resource&& x) noexcept {
    if (handle) delete handle;
    handle = x.handle;
    x.handle = nullptr;
    return *this;
  }
  ~resource() noexcept {
    if (handle) delete handle;
  }
  int* handle = nullptr;
  friend bool operator==(resource const& r, int i) noexcept { return *r.handle == i; }
  friend bool operator==(int i, resource const& r) noexcept { return r == i; }
  friend bool operator!=(int i, resource const& r) noexcept { return !(r == i); }
  friend bool operator!=(resource const& r, int i) noexcept { return !(r == i); }
};

using darray = cont::dynamic_array<resource>;

void canDefaultConstructDynamicArray() {
  darray da;
  EXPECT_EQ(0u, da.capacity());
  EXPECT_TRUE(da.empty());
}

void canCreateDynamicArrayWithGivenCapacity() {
  darray da1(1);
  darray da3(3);
  EXPECT_EQ(1u, da1.capacity());
  EXPECT_TRUE(da1.empty());

  EXPECT_EQ(3u, da3.capacity());
  EXPECT_TRUE(da3.empty());
}

void canMoveConstructDynamicArray() {
  darray da1(1);
  {
    EXPECT_EQ(1u, da1.capacity());
    EXPECT_TRUE(da1.empty());
  }

  darray da(std::move(da1));
  EXPECT_EQ(0u, da1.capacity());
  EXPECT_TRUE(da1.empty());
  EXPECT_EQ(1u, da.capacity());
  EXPECT_TRUE(da.empty());
}

void canEmplaceBackElement() {
  darray da(1);
  {
    EXPECT_EQ(1u, da.capacity());
    EXPECT_EQ(0u, da.size());
    EXPECT_TRUE(da.empty());
  }

  da.emplace_back(7);
  EXPECT_EQ(1u, da.capacity());
  EXPECT_EQ(1u, da.size());
  EXPECT_FALSE(da.empty());
  EXPECT_EQ(7, da[0]);
}

void canPopBackElement() {
  darray da(1);
  {
    EXPECT_EQ(1u, da.capacity());
    da.emplace_back(7);
    EXPECT_EQ(1u, da.capacity());
    EXPECT_EQ(1u, da.size());
    EXPECT_FALSE(da.empty());
  }

  da.pop_back();
  EXPECT_EQ(1u, da.capacity());
  EXPECT_EQ(0u, da.size());
  EXPECT_TRUE(da.empty());
}

void canUseBeginAndEnd() {
  darray da0;
  darray da1(1);
  darray da2(2);
  {
    EXPECT_EQ(da0.begin(), da0.end());
    EXPECT_EQ(da1.begin(), da1.end());
    EXPECT_EQ(da2.begin(), da2.end());
  }

  da1.emplace_back(11);
  da2.emplace_back(13);
  {
    EXPECT_EQ(da1.begin() + 1, da1.end());
    EXPECT_EQ(da2.begin() + 1, da2.end());
  }

  da2.emplace_back(17);
  EXPECT_EQ(da2.begin() + 2, da2.end());
}

void canEraseElement() {
  darray da(3);
  {
    da.emplace_back(7);
    da.emplace_back(11);
    da.emplace_back(13);
    EXPECT_EQ(3u, da.size());
    EXPECT_TRUE(da.full());
    EXPECT_EQ(7, da[0]);
    EXPECT_EQ(11, da[1]);
    EXPECT_EQ(13, da[2]);
  }

  da.erase(da.begin());
  {
    EXPECT_EQ(2u, da.size());
    EXPECT_FALSE(da.full());
    EXPECT_EQ(11, da[0]);
    EXPECT_EQ(13, da[1]);
  }

  da.erase(da.begin() + 1);
  {
    EXPECT_EQ(1u, da.size());
    EXPECT_EQ(11, da[0]);
  }

  da.erase(da.begin());
  EXPECT_EQ(3u, da.capacity());
  EXPECT_TRUE(da.empty());
}

void canReleaseContent() {
  darray da(7);
  {
    da.emplace_back(5);
    da.emplace_back(7);
    da.emplace_back(11);
    da.emplace_back(13);
  }

  auto alloc = da.get_allocator();
  darray::pointer first, last, end;
  std::tie(first, last, end) = da.release();
  EXPECT_EQ(4, last - first);
  alloc.deallocate(first, end - first);
}

int main() {
  canDefaultConstructDynamicArray();
  canCreateDynamicArrayWithGivenCapacity();
  canMoveConstructDynamicArray();
  canEmplaceBackElement();
  canPopBackElement();
  canUseBeginAndEnd();
  canEraseElement();
  canReleaseContent();
  return 0;
}
<|endoftext|>


<commit_before>#if defined(_MSC_VER) && _MSC_VER >= 1400
#pragma warning(push)
#pragma warning(disable:4996)
#endif

#include "word_count.h"
#include <vector>
#include <locale>
#include <boost/algorithm/string.hpp>

using namespace std;

namespace word_count
{

map<string, int> words(string const& text)
{
    // A less than ideal solution since I can't get regex building in GCC on Travis
    map<string, int> count;
    string normalized = boost::to_lower_copy(text);
    for (unsigned int i = 0; i < normalized.length(); i++)
    {
        auto c = normalized[i];
        normalized[i] = (isalnum(c, locale()) || c == '\'') ? c : ' ';
    }
    vector<string> words;
    boost::split(words, normalized, boost::is_any_of("\t "));
    for (auto const& word : words)
    {
        auto const& trimmed = boost::trim_copy_if(word, boost::is_any_of("' "));
        if (!trimmed.empty())
        {
            count[trimmed]++;
        }
    }
    return count;
}

}

#if defined(_MSC_VER) && _MSC_VER >= 1400
#pragma warning(pop)
#endif
<commit_msg>Compose Method on words().<commit_after>#include "word_count.h"
#include <algorithm>
#include <cctype>
#include <iterator>
#include <vector>
#include <boost/algorithm/string.hpp>

using namespace std;

namespace
{

string normalize_text(string const& text)
{
    string normalized;
    transform(text.begin(), text.end(), back_inserter(normalized),
        [](const char c) { return (isalnum(c) || c == '\'') ? tolower(c) : ' '; });
    return normalized;
}

string trim_word(string const& word)
{
    return boost::trim_copy_if(word, boost::is_any_of("' "));
}

vector<string> split_text_into_words(string const& text)
{
    vector<string> words;
    boost::split(words, text, boost::is_any_of("\t "));
    transform(words.begin(), words.end(), words.begin(), trim_word);
    return words;
}

}

namespace word_count
{

map<string, int> words(string const& text)
{
    map<string, int> count;
    for (auto const& word : split_text_into_words(normalize_text(text)))
    {
        if (!word.empty())
        {
            ++count[word];
        }
    }
    return count;
}

}
<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2022, LH_Mouse. All wrongs reserved.

#include "../precompiled.ipp"
#include "tcp_socket.hpp"
#include "../static/async_logger.hpp"
#include "../utils.hpp"
#include <sys/socket.h>
#include <netinet/tcp.h>

namespace poseidon {

TCP_Socket::
TCP_Socket(unique_posix_fd&& fd)
  : Abstract_Socket(::std::move(fd))
  {
    // Use `TCP_NODELAY`. Errors are ignored.
    int ival = 1;
    ::setsockopt(this->fd(), IPPROTO_TCP, TCP_NODELAY, &ival, sizeof(ival));
  }

TCP_Socket::
TCP_Socket(int family)
  : Abstract_Socket(family, SOCK_STREAM, IPPROTO_TCP)
  {
    // Use `TCP_NODELAY`. Errors are ignored.
    int ival = 1;
    ::setsockopt(this->fd(), IPPROTO_TCP, TCP_NODELAY, &ival, sizeof(ival));
  }

TCP_Socket::
~TCP_Socket()
  {
  }

void
TCP_Socket::
do_abstract_socket_on_readable()
  {
    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_read_queue(io_lock);

    // Try getting some bytes from this socket.
    queue.reserve(0xFFFFU);
    size_t datalen;

  try_io:
    datalen = queue.capacity();
    ::ssize_t r = ::recv(this->fd(), queue.mut_end(), datalen, 0);
    datalen = (size_t) r;

    if(r < 0) {
      switch(errno) {
        case EINTR:
          goto try_io;

#if EWOULDBLOCK != EAGAIN
        case EAGAIN:
#endif
        case EWOULDBLOCK:
          return;
      }

      POSEIDON_THROW((
          "Error reading TCP socket",
          "[`recv()` failed: $3]",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this), format_errno());
    }

    if(r == 0) {
      ::shutdown(this->fd(), SHUT_RDWR);
      POSEIDON_LOG_INFO(("Shut down TCP connection: remote = $1"), this->get_remote_address());
      return;
    }

    // Accept these data.
    queue.accept(datalen);
    this->do_on_tcp_stream(queue);
  }

void
TCP_Socket::
do_abstract_socket_on_writable()
  {
    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_write_queue(io_lock);

    if(queue.empty())
      return;

    // Send some bytes from the write queue.
    size_t datalen;

  try_io:
    datalen = queue.size();
    ::ssize_t r = ::send(this->fd(), queue.begin(), datalen, 0);
    datalen = (size_t) r;

    if(r < 0) {
      switch(errno) {
        case EINTR:
          goto try_io;

#if EWOULDBLOCK != EAGAIN
        case EAGAIN:
#endif
        case EWOULDBLOCK:
          return;
      }

      POSEIDON_THROW((
          "Error writing TCP socket",
          "[`send()` failed: $3]",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this), format_errno());
    }

    // Remove sent bytes from the write queue.
    queue.discard(datalen);
  }

void
TCP_Socket::
do_abstract_socket_on_exception(exception& stdex)
  {
    this->abort();

    POSEIDON_LOG_WARN((
        "Aborting connection due to exception: $3",
        "[TCP socket `$1` (class `$2`)]"),
        this, typeid(*this), stdex);
  }

const Socket_Address&
TCP_Socket::
get_remote_address() const
  {
    // Get the socket name and cache it.
    this->m_peername_once.call(
      [this] {
        ::socklen_t addrlen = (::socklen_t) this->m_peername.capacity();
        if(::getpeername(this->fd(), this->m_peername.mut_addr(), &addrlen) != 0)
          POSEIDON_THROW((
              "Could not get local address of socket",
              "[`getpeername()` failed: $1]"),
              format_errno());

        // Accept the address.
        this->m_peername.set_size(addrlen);
      });
    return this->m_peername;
  }

bool
TCP_Socket::
tcp_send(const char* data, size_t size)
  {
    if(size && !data)
      POSEIDON_THROW((
          "Null data pointer",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this));

    // If this socket has been marked closed, fail immediately.
    if(this->socket_state() == socket_state_closed)
      return false;

    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_write_queue(io_lock);

    // Append data for sending.
    queue.putn(data, size);

    // Try writing once. This is essential for the edge-triggered epoll to work
    // reliably, because the level-triggered epoll does not check for `EPOLLOUT` by
    // default. If the packet has been sent anyway, discard it from the write queue.
    this->do_abstract_socket_on_writable();
    return true;
  }

bool
TCP_Socket::
tcp_send(const linear_buffer& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

bool
TCP_Socket::
tcp_send(const cow_string& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

bool
TCP_Socket::
tcp_send(const string& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

}  // namespace poseidon
<commit_msg>tcp_socket: Minor<commit_after>// This file is part of Poseidon.
// Copyleft 2022, LH_Mouse. All wrongs reserved.

#include "../precompiled.ipp"
#include "tcp_socket.hpp"
#include "../static/async_logger.hpp"
#include "../utils.hpp"
#include <sys/socket.h>
#include <netinet/tcp.h>

namespace poseidon {

TCP_Socket::
TCP_Socket(unique_posix_fd&& fd)
  : Abstract_Socket(::std::move(fd))
  {
    // Use `TCP_NODELAY`. Errors are ignored.
    int ival = 1;
    ::setsockopt(this->fd(), IPPROTO_TCP, TCP_NODELAY, &ival, sizeof(ival));
  }

TCP_Socket::
TCP_Socket(int family)
  : Abstract_Socket(family, SOCK_STREAM, IPPROTO_TCP)
  {
    // Use `TCP_NODELAY`. Errors are ignored.
    int ival = 1;
    ::setsockopt(this->fd(), IPPROTO_TCP, TCP_NODELAY, &ival, sizeof(ival));
  }

TCP_Socket::
~TCP_Socket()
  {
  }

void
TCP_Socket::
do_abstract_socket_on_readable()
  {
    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_read_queue(io_lock);

    // Try getting some bytes from this socket.
    queue.reserve(0xFFFFU);
    size_t datalen;

  try_io:
    datalen = queue.capacity();
    ::ssize_t r = ::recv(this->fd(), queue.mut_end(), datalen, 0);
    datalen = (size_t) r;

    if(r == 0) {
      // Shut the connection down. Semi-open connections are not supported.
      POSEIDON_LOG_INFO(("Closing TCP connection: remote = $1"), this->get_remote_address());
      ::shutdown(this->fd(), SHUT_RDWR);
      return;
    }

    if(r < 0) {
      switch(errno) {
        case EINTR:
          goto try_io;

#if EWOULDBLOCK != EAGAIN
        case EAGAIN:
#endif
        case EWOULDBLOCK:
          return;
      }

      POSEIDON_THROW((
          "Error reading TCP socket",
          "[`recv()` failed: $3]",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this), format_errno());
    }

    // Accept these data.
    queue.accept(datalen);
    this->do_on_tcp_stream(queue);
  }

void
TCP_Socket::
do_abstract_socket_on_writable()
  {
    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_write_queue(io_lock);

    if(queue.empty())
      return;

    // Send some bytes from the write queue.
    size_t datalen;

  try_io:
    datalen = queue.size();
    ::ssize_t r = ::send(this->fd(), queue.begin(), datalen, 0);
    datalen = (size_t) r;

    if(r < 0) {
      switch(errno) {
        case EINTR:
          goto try_io;

#if EWOULDBLOCK != EAGAIN
        case EAGAIN:
#endif
        case EWOULDBLOCK:
          return;
      }

      POSEIDON_THROW((
          "Error writing TCP socket",
          "[`send()` failed: $3]",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this), format_errno());
    }

    // Remove sent bytes from the write queue.
    queue.discard(datalen);
  }

void
TCP_Socket::
do_abstract_socket_on_exception(exception& stdex)
  {
    this->abort();

    POSEIDON_LOG_WARN((
        "Aborting connection due to exception: $3",
        "[TCP socket `$1` (class `$2`)]"),
        this, typeid(*this), stdex);
  }

const Socket_Address&
TCP_Socket::
get_remote_address() const
  {
    // Get the socket name and cache it.
    this->m_peername_once.call(
      [this] {
        ::socklen_t addrlen = (::socklen_t) this->m_peername.capacity();
        if(::getpeername(this->fd(), this->m_peername.mut_addr(), &addrlen) != 0)
          POSEIDON_THROW((
              "Could not get local address of socket",
              "[`getpeername()` failed: $1]"),
              format_errno());

        // Accept the address.
        this->m_peername.set_size(addrlen);
      });
    return this->m_peername;
  }

bool
TCP_Socket::
tcp_send(const char* data, size_t size)
  {
    if(size && !data)
      POSEIDON_THROW((
          "Null data pointer",
          "[TCP socket `$1` (class `$2`)]"),
          this, typeid(*this));

    // If this socket has been marked closed, fail immediately.
    if(this->socket_state() == socket_state_closed)
      return false;

    recursive_mutex::unique_lock io_lock;
    auto& queue = this->do_abstract_socket_lock_write_queue(io_lock);

    // Append data for sending.
    queue.putn(data, size);

    // Try writing once. This is essential for the edge-triggered epoll to work
    // reliably, because the level-triggered epoll does not check for `EPOLLOUT` by
    // default. If the packet has been sent anyway, discard it from the write queue.
    this->do_abstract_socket_on_writable();
    return true;
  }

bool
TCP_Socket::
tcp_send(const linear_buffer& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

bool
TCP_Socket::
tcp_send(const cow_string& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

bool
TCP_Socket::
tcp_send(const string& data)
  {
    return this->tcp_send(data.data(), data.size());
  }

}  // namespace poseidon
<|endoftext|>