<commit_before>#include <iostream>
#include <unistd.h>

#include "libs/catch/catch.hpp"

#include "src/dopt_node.h"

TEST_CASE("entangle|dopt_node-enc") {
	auto n = entangle::OTNode(8888, 100);
	entangle::upd_t u = { entangle::del, 100, 'c' };
	REQUIRE(n.enc_upd_t(u).compare("1:100:c") == 0);
	REQUIRE(n.cmp_upd_t({ entangle::del, 100, 'c'}, { entangle::del, 100, 'c' }) == true);
	REQUIRE(n.cmp_upd_t({ entangle::del, 100, 'c'}, { entangle::del, 100, 'd' }) == false);
	REQUIRE(n.cmp_upd_t(n.dec_upd_t("1:100:c"), { entangle::del, 100, 'c' }) == true);
}

TEST_CASE("entangle|dopt_node-convergence") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 2);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE(x.join("localhost", 8000) == true);
	sleep(1);

	CHECK(s.get_context().compare("") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '2') == true);
	sleep(1);
	CHECK(s.get_context().compare("211") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.del(1) == true);
	sleep(1);
	CHECK(s.get_context().compare("21") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(s.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
}

TEST_CASE("entangle|dopt_node-daemon") {
	auto n = entangle::OTNode(8888, 100);
	auto m = entangle::OTNode(8889, 100);

	REQUIRE(m.join("localhost", 8888) == false);

	REQUIRE_NOTHROW(n.up());
	REQUIRE_NOTHROW(n.dn());

	REQUIRE_NOTHROW(n.up());
	REQUIRE_NOTHROW(m.up());
	REQUIRE(m.join("localhost", 8888) == true);
	sleep(1);
	REQUIRE(m.size() == 1);
	REQUIRE(n.size() == 1);
	REQUIRE(m.join("localhost", 8888) == false);
	REQUIRE(n.join("localhost", 8889) == false);
	REQUIRE(m.size() == 1);
	REQUIRE(n.size() == 1);
	REQUIRE(m.drop("localhost", 8888) == true);
	sleep(1);
	REQUIRE(m.size() == 0);
	REQUIRE(n.size() == 0);
	REQUIRE_NOTHROW(m.dn());
	REQUIRE_NOTHROW(n.dn());

	// auto-call OTNode::dn on stack unwind
	REQUIRE_NOTHROW(n.up());
	sleep(1);
}

TEST_CASE("entangle|dopt_node-topography") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 2);
	auto y = entangle::OTNode(8051, 1);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 1);

	/**
	 * single node, single server topology
	 */
	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);

	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 2);

	/**
	 * multi node, single server topology
	 */
	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 0);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());

	/**
	 * multi-layer tree topology
	 */
	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8050) == true);
	REQUIRE(s.size() == 1);
	REQUIRE(x.size() == 2);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	REQUIRE(s.get_context().compare("1") == 0);
	REQUIRE(x.get_context().compare(s.get_context()) == 0);
	REQUIRE(y.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8050) == true);
	sleep(1);
	REQUIRE(s.size() == 0);
	REQUIRE(x.size() == 0);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());
}

TEST_CASE("entangle|dopt_node-concurrent") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 1);
	auto y = entangle::OTNode(8051, 1);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 2);

	/**
	 * concurrent update checking
	 */
	REQUIRE(x.ins(0, '1') == true);
	REQUIRE(y.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	REQUIRE(y.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 0);

	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	REQUIRE(y.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);

	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());
}
<commit_msg>more tests<commit_after>#include <iostream>
#include <unistd.h>

#include "libs/catch/catch.hpp"

#include "src/dopt_node.h"

TEST_CASE("entangle|dopt_node-enc") {
	auto n = entangle::OTNode(8888, 100);
	entangle::upd_t u = { entangle::del, 100, 'c' };
	REQUIRE(n.enc_upd_t(u).compare("1:100:c") == 0);
	REQUIRE(n.cmp_upd_t({ entangle::del, 100, 'c'}, { entangle::del, 100, 'c' }) == true);
	REQUIRE(n.cmp_upd_t({ entangle::del, 100, 'c'}, { entangle::del, 100, 'd' }) == false);
	REQUIRE(n.cmp_upd_t(n.dec_upd_t("1:100:c"), { entangle::del, 100, 'c' }) == true);
}

TEST_CASE("entangle|dopt_node-convergence") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 2);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE(x.join("localhost", 8000) == true);
	sleep(1);

	CHECK(s.get_context().compare("") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.ins(0, '2') == true);
	sleep(1);
	CHECK(s.get_context().compare("211") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.del(1) == true);
	sleep(1);
	CHECK(s.get_context().compare("21") == 0);
	CHECK(x.get_context().compare(s.get_context()) == 0);

	REQUIRE(s.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
}

TEST_CASE("entangle|dopt_node-daemon") {
	auto n = entangle::OTNode(8888, 100);
	auto m = entangle::OTNode(8889, 100);

	REQUIRE(m.join("localhost", 8888) == false);

	REQUIRE_NOTHROW(n.up());
	REQUIRE_NOTHROW(n.dn());

	REQUIRE_NOTHROW(n.up());
	REQUIRE_NOTHROW(m.up());
	REQUIRE(m.join("localhost", 8888) == true);
	sleep(1);
	REQUIRE(m.size() == 1);
	REQUIRE(n.size() == 1);
	REQUIRE(m.join("localhost", 8888) == false);
	REQUIRE(n.join("localhost", 8889) == false);
	REQUIRE(m.size() == 1);
	REQUIRE(n.size() == 1);
	REQUIRE(m.drop("localhost", 8888) == true);
	sleep(1);
	REQUIRE(m.size() == 0);
	REQUIRE(n.size() == 0);
	REQUIRE_NOTHROW(m.dn());
	REQUIRE_NOTHROW(n.dn());

	// auto-call OTNode::dn on stack unwind
	REQUIRE_NOTHROW(n.up());
	sleep(1);
}

TEST_CASE("entangle|dopt_node-topography") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 2);
	auto y = entangle::OTNode(8051, 1);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 1);

	/**
	 * single node, single server topology
	 */
	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);

	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 2);

	/**
	 * multi node, single server topology
	 */
	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 0);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());

	/**
	 * multi-layer tree topology
	 */
	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8050) == true);
	REQUIRE(s.size() == 1);
	REQUIRE(x.size() == 2);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	REQUIRE(s.get_context().compare("1") == 0);
	REQUIRE(x.get_context().compare(s.get_context()) == 0);
	REQUIRE(y.get_context().compare(s.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8050) == true);
	sleep(1);
	REQUIRE(s.size() == 0);
	REQUIRE(x.size() == 0);
	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());
}

TEST_CASE("entangle|dopt_node-concurrent") {
	auto s = entangle::OTNode(8000, 100);
	auto x = entangle::OTNode(8050, 1);
	auto y = entangle::OTNode(8051, 1);

	REQUIRE_NOTHROW(s.up());
	REQUIRE_NOTHROW(x.up());
	REQUIRE_NOTHROW(y.up());
	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 2);

	/**
	 * concurrent update checking
	 */
	REQUIRE(x.ins(0, '1') == true);
	REQUIRE(y.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	REQUIRE(y.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);
	REQUIRE(s.size() == 0);

	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.del(0) == true);
	REQUIRE(x.del(0) == true);
	sleep(1);
	CHECK(s.get_context().compare("") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.join("localhost", 8000) == true);
	REQUIRE(y.join("localhost", 8000) == true);
	sleep(1);

	REQUIRE(x.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("1") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(y.ins(0, '1') == true);
	sleep(1);
	CHECK(s.get_context().compare("11") == 0);
	CHECK(s.get_context().compare(x.get_context()) == 0);
	CHECK(s.get_context().compare(y.get_context()) == 0);

	REQUIRE(x.drop("localhost", 8000) == true);
	REQUIRE(y.drop("localhost", 8000) == true);
	sleep(1);

	REQUIRE_NOTHROW(s.dn());
	REQUIRE_NOTHROW(x.dn());
	REQUIRE_NOTHROW(y.dn());
}
<|endoftext|>


<commit_before>/**
 * Created by Jian Chen
 * @since  2016.08.14
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#ifndef _WIN32

#include <socket/net/net_socket.hpp>
#include <socket/net/net_error.hpp>
#include <chen/base/num.hpp>
#include <chen/sys/sys.hpp>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

// -----------------------------------------------------------------------------
// helper
namespace
{
    int af(chen::net::socket::Family family)
    {
        switch (family)
        {
            case chen::net::socket::Family::IPv4:
                return AF_INET;

            case chen::net::socket::Family::IPv6:
                return AF_INET6;

            case chen::net::socket::Family::Unix:
                return AF_UNIX;
        }

        return 0;
    }

    int type(chen::net::socket::Protocol protocol)
    {
        switch (protocol)
        {
            case chen::net::socket::Protocol::TCP:
                return SOCK_STREAM;

            case chen::net::socket::Protocol::UDP:
                return SOCK_DGRAM;

            case chen::net::socket::Protocol::RAW:
                return SOCK_RAW;
        }

        return 0;
    }
}

// -----------------------------------------------------------------------------
// impl
struct chen::net::socket::impl
{
    int _fd = 0;  // socket file descriptor
};

// -----------------------------------------------------------------------------
// socket
chen::net::socket::socket(Family family, Protocol protocol) : _impl(new impl)
{
    this->reset(family, protocol);
}

chen::net::socket::~socket()
{
    this->close();
}

// reset
void chen::net::socket::reset(Family family, Protocol protocol)
{
    if (this->_impl->_fd && !this->close())
        throw error_socket("socket: " + sys::error());

    auto fd = ::socket(af(family), type(protocol), 0);
    if (fd < 0)
        throw error_socket("socket: " + sys::error());

    this->_family    = family;
    this->_protocol  = protocol;
    this->_impl->_fd = fd;
}

// close
bool chen::net::socket::close() noexcept
{
    if (!this->_impl->_fd)
        return true;

    if (!::close(this->_impl->_fd))
    {
        this->_impl->_fd = 0;
        return true;
    }

    return false;
}

bool chen::net::socket::shutdown(Shutdown flag) noexcept
{
    if (!this->_impl->_fd)
        return true;

    if (flag == Shutdown::Read)
        return !::shutdown(this->_impl->_fd, SHUT_RD);
    else if (flag == Shutdown::Write)
        return !::shutdown(this->_impl->_fd, SHUT_WR);
    else if (flag == Shutdown::Both)
        return !::shutdown(this->_impl->_fd, SHUT_RDWR);

    return true;
}

// info
chen::net::endpoint chen::net::socket::local() const noexcept
{

}

chen::net::endpoint chen::net::socket::remote() const noexcept
{
    if (!this->_impl->_fd)
        return nullptr;

    switch (this->_family)
    {
        case socket::Family::IPv4:
        {
            struct sockaddr_in in{};
            socklen_t len = sizeof(in);

            if (::getpeername(this->_impl->_fd, (struct sockaddr*)&in, &len) != 0)
                return nullptr;

            return endpoint(address(num::swap(in.sin_addr.s_addr)), num::swap(in.sin_port));
        }

        case socket::Family::IPv6:
        {
            struct sockaddr_in6 in6{};
            socklen_t len = sizeof(in6);

            if (::getpeername(this->_impl->_fd, (struct sockaddr*)&in6, &len) != 0)
                return nullptr;

            std::array<std::uint8_t, 16> addr;
            std::copy(in6.sin6_addr.s6_addr, in6.sin6_addr.s6_addr + 16, addr.begin());

            return endpoint(address(version6(addr, 128, in6.sin6_scope_id)), num::swap(in6.sin6_port));
        }

        default:
            return nullptr;
    }
}

#endif<commit_msg>socket: implement get local endpoint<commit_after>/**
 * Created by Jian Chen
 * @since  2016.08.14
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#ifndef _WIN32

#include <socket/net/net_socket.hpp>
#include <socket/net/net_error.hpp>
#include <chen/base/num.hpp>
#include <chen/sys/sys.hpp>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

// -----------------------------------------------------------------------------
// helper
namespace
{
    int af(chen::net::socket::Family family)
    {
        switch (family)
        {
            case chen::net::socket::Family::IPv4:
                return AF_INET;

            case chen::net::socket::Family::IPv6:
                return AF_INET6;

            case chen::net::socket::Family::Unix:
                return AF_UNIX;
        }

        return 0;
    }

    int type(chen::net::socket::Protocol protocol)
    {
        switch (protocol)
        {
            case chen::net::socket::Protocol::TCP:
                return SOCK_STREAM;

            case chen::net::socket::Protocol::UDP:
                return SOCK_DGRAM;

            case chen::net::socket::Protocol::RAW:
                return SOCK_RAW;
        }

        return 0;
    }
}

// -----------------------------------------------------------------------------
// impl
struct chen::net::socket::impl
{
    int _fd = 0;  // socket file descriptor
};

// -----------------------------------------------------------------------------
// socket
chen::net::socket::socket(Family family, Protocol protocol) : _impl(new impl)
{
    this->reset(family, protocol);
}

chen::net::socket::~socket()
{
    this->close();
}

// reset
void chen::net::socket::reset(Family family, Protocol protocol)
{
    if (this->_impl->_fd && !this->close())
        throw error_socket("socket: " + sys::error());

    auto fd = ::socket(af(family), type(protocol), 0);
    if (fd < 0)
        throw error_socket("socket: " + sys::error());

    this->_family    = family;
    this->_protocol  = protocol;
    this->_impl->_fd = fd;
}

// close
bool chen::net::socket::close() noexcept
{
    if (!this->_impl->_fd)
        return true;

    if (!::close(this->_impl->_fd))
    {
        this->_impl->_fd = 0;
        return true;
    }

    return false;
}

bool chen::net::socket::shutdown(Shutdown flag) noexcept
{
    if (!this->_impl->_fd)
        return true;

    if (flag == Shutdown::Read)
        return !::shutdown(this->_impl->_fd, SHUT_RD);
    else if (flag == Shutdown::Write)
        return !::shutdown(this->_impl->_fd, SHUT_WR);
    else if (flag == Shutdown::Both)
        return !::shutdown(this->_impl->_fd, SHUT_RDWR);

    return true;
}

// info
chen::net::endpoint chen::net::socket::local() const noexcept
{
    if (!this->_impl->_fd)
        return nullptr;

    switch (this->_family)
    {
        case socket::Family::IPv4:
        {
            struct sockaddr_in in{};
            socklen_t len = sizeof(in);

            if (::getsockname(this->_impl->_fd, (struct sockaddr*)&in, &len) != 0)
                return nullptr;

            return endpoint(address(num::swap(in.sin_addr.s_addr)), num::swap(in.sin_port));
        }

        case socket::Family::IPv6:
        {
            struct sockaddr_in6 in6{};
            socklen_t len = sizeof(in6);

            if (::getsockname(this->_impl->_fd, (struct sockaddr*)&in6, &len) != 0)
                return nullptr;

            return endpoint(address(version6(version6::array(in6.sin6_addr.s6_addr), 128, in6.sin6_scope_id)),
                            num::swap(in6.sin6_port));
        }

        default:
            return nullptr;
    }
}

chen::net::endpoint chen::net::socket::remote() const noexcept
{
    if (!this->_impl->_fd)
        return nullptr;

    switch (this->_family)
    {
        case socket::Family::IPv4:
        {
            struct sockaddr_in in{};
            socklen_t len = sizeof(in);

            if (::getpeername(this->_impl->_fd, (struct sockaddr*)&in, &len) != 0)
                return nullptr;

            return endpoint(address(num::swap(in.sin_addr.s_addr)), num::swap(in.sin_port));
        }

        case socket::Family::IPv6:
        {
            struct sockaddr_in6 in6{};
            socklen_t len = sizeof(in6);

            if (::getpeername(this->_impl->_fd, (struct sockaddr*)&in6, &len) != 0)
                return nullptr;

            return endpoint(address(version6(version6::array(in6.sin6_addr.s6_addr), 128, in6.sin6_scope_id)),
                            num::swap(in6.sin6_port));
        }

        default:
            return nullptr;
    }
}

#endif<|endoftext|>


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

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

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

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

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

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

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

#include "utils/lru.h"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE csvreader_test
#include <boost/test/unit_test.hpp>

struct Fun {
    typedef int const& argument_type;
    typedef int result_type;
    size_t& nb_call;
    Fun(size_t& nb): nb_call(nb) {}
    int operator()(const int& i) const { ++nb_call; return i * 2; }
};

BOOST_AUTO_TEST_CASE(simple_lru) {
    size_t nb_call = 0;
    auto lru = navitia::make_lru(Fun(nb_call), 2);

    // cache = { 1 -> 2 }
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 1);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 1);

    // cache = { 1 -> 2, 2 -> 4 }
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 2);
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 2);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 2);

    // cache = { 1 -> 2, 3 -> 6 }
    BOOST_CHECK_EQUAL(lru(3), 6);
    BOOST_CHECK_EQUAL(nb_call, 3);
    BOOST_CHECK_EQUAL(lru(3), 6);
    BOOST_CHECK_EQUAL(nb_call, 3);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 3);

    // cache = { 1 -> 2, 2 -> 4 }
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 4);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 4);
}
<commit_msg>add comments in lru_test.cpp<commit_after>/* Copyright © 2001-2015, Canal TP and/or its affiliates. All rights reserved.

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

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

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

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

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

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

#include "utils/lru.h"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE csvreader_test
#include <boost/test/unit_test.hpp>

struct Fun {
    typedef int const& argument_type;
    typedef int result_type;
    size_t& nb_call;
    Fun(size_t& nb): nb_call(nb) {}
    int operator()(const int& i) const { ++nb_call; return i * 2; }
};

BOOST_AUTO_TEST_CASE(simple_lru) {
    size_t nb_call = 0;

    // a Lru with 2 elements cached
    auto lru = navitia::make_lru(Fun(nb_call), 2);

    // cache = { 1 -> 2 }
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 1);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 1);

    // cache = { 1 -> 2, 2 -> 4 }
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 2);
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 2);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 2);

    // cache = { 1 -> 2, 3 -> 6 }
    // As "1" is the last used element, and the cache can only have 2
    // elements, the entry "2" is removed.
    BOOST_CHECK_EQUAL(lru(3), 6);
    BOOST_CHECK_EQUAL(nb_call, 3);
    BOOST_CHECK_EQUAL(lru(3), 6);
    BOOST_CHECK_EQUAL(nb_call, 3);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 3);

    // cache = { 1 -> 2, 2 -> 4 }
    // As "2" was calculated earlier, but removed because of cache
    // size, we need to call the function to get the value.
    BOOST_CHECK_EQUAL(lru(2), 4);
    BOOST_CHECK_EQUAL(nb_call, 4);
    BOOST_CHECK_EQUAL(lru(1), 2);
    BOOST_CHECK_EQUAL(nb_call, 4);
}
<|endoftext|>


<commit_before>#include <boost/lexical_cast.hpp>
#include <vigra/impex.hxx>

#include <util/Logger.h>

#include "ImageStackDirectoryWriter.h"

logger::LogChannel imagestackdirectorywriterlog("imagestackdirectorywriterlog", "[ImageStackDirectoryWriter] ");

ImageStackDirectoryWriter::ImageStackDirectoryWriter(std::string directory, std::string basename) :
	_directory(directory),
	_basename(basename),
	_dirty(false) {

	registerInput(_stack, "image stack");

	_stack.registerBackwardCallback(&ImageStackDirectoryWriter::onModified, this);
}

void
ImageStackDirectoryWriter::onModified(const pipeline::Modified&) {

	boost::mutex::scoped_lock lock(_dirtyMutex);

	LOG_DEBUG(imagestackdirectorywriterlog) << "stack changed" << std::endl;

	_dirty = true;
}

bool
ImageStackDirectoryWriter::write(std::string basename) {

	{
		boost::mutex::scoped_lock lock(_dirtyMutex);

		if (!_dirty)
			return false;

		_dirty = false;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "attempting to write stack" << std::endl;

	if (!_stack) {

		LOG_ERROR(imagestackdirectorywriterlog) << "no input image stack set" << std::endl;
		return false;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "requesting image update" << std::endl;

	updateInputs();

	boost::unique_lock<boost::shared_mutex> lock(_stack->getMutex());

	// save to file

	unsigned int i = 0;

	foreach (boost::shared_ptr<Image> image, *_stack) {

		std::stringstream number;
		number << std::setw(8) << std::setfill('0');
		number << i;

		std::string filename = _directory + "/" + _basename + basename + number.str() + ".tiff";
		vigra::exportImage(vigra::srcImageRange(*image), vigra::ImageExportInfo(filename.c_str()).setPixelType("FLOAT"));

		i++;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "images written" << std::endl;

	return true;
}
<commit_msg>changed ImageStackDirectoryWriter back to writing pngs<commit_after>#include <boost/lexical_cast.hpp>
#include <vigra/impex.hxx>

#include <util/Logger.h>

#include "ImageStackDirectoryWriter.h"

logger::LogChannel imagestackdirectorywriterlog("imagestackdirectorywriterlog", "[ImageStackDirectoryWriter] ");

ImageStackDirectoryWriter::ImageStackDirectoryWriter(std::string directory, std::string basename) :
	_directory(directory),
	_basename(basename),
	_dirty(false) {

	registerInput(_stack, "image stack");

	_stack.registerBackwardCallback(&ImageStackDirectoryWriter::onModified, this);
}

void
ImageStackDirectoryWriter::onModified(const pipeline::Modified&) {

	boost::mutex::scoped_lock lock(_dirtyMutex);

	LOG_DEBUG(imagestackdirectorywriterlog) << "stack changed" << std::endl;

	_dirty = true;
}

bool
ImageStackDirectoryWriter::write(std::string basename) {

	{
		boost::mutex::scoped_lock lock(_dirtyMutex);

		if (!_dirty)
			return false;

		_dirty = false;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "attempting to write stack" << std::endl;

	if (!_stack) {

		LOG_ERROR(imagestackdirectorywriterlog) << "no input image stack set" << std::endl;
		return false;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "requesting image update" << std::endl;

	updateInputs();

	boost::unique_lock<boost::shared_mutex> lock(_stack->getMutex());

	// save to file

	unsigned int i = 0;

	foreach (boost::shared_ptr<Image> image, *_stack) {

		std::stringstream number;
		number << std::setw(8) << std::setfill('0');
		number << i;

		std::string filename = _directory + "/" + _basename + basename + number.str() + ".png";
		vigra::exportImage(vigra::srcImageRange(*image), vigra::ImageExportInfo(filename.c_str()));

		i++;
	}

	LOG_DEBUG(imagestackdirectorywriterlog) << "images written" << std::endl;

	return true;
}
<|endoftext|>


<commit_before>#include <cstdint>
#include <cuda_runtime.h>
#include <nba/core/shiftedint.hh>
#include <nba/framework/datablock_shared.hh>
#include <gtest/gtest.h>
#include <nba/engines/cuda/test.hh>
#if 0
#require <engines/cuda/test.o>
#endif

using namespace std;
using namespace nba;

#ifdef USE_CUDA

TEST(CUDADeviceTest, Initialization) {
    ASSERT_EQ(cudaSuccess, cudaSetDevice(0));
    ASSERT_EQ(cudaSuccess, cudaDeviceReset());
}

TEST(CUDADeviceTest, NoopKernel) {
    ASSERT_EQ(cudaSuccess, cudaSetDevice(0));
    void *k = get_test_kernel_noop();
    EXPECT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), nullptr, 0, 0));
    EXPECT_EQ(cudaSuccess, cudaDeviceSynchronize());
    ASSERT_EQ(cudaSuccess, cudaDeviceReset());
}

class CUDAStructTest : public ::testing::Test {
protected:
    virtual void SetUp() {
        cudaSetDevice(0);
    }

    virtual void TearDown() {
        cudaDeviceReset();
    }
};

TEST(CUDAStructTest, ShfitedIntSizeCheck) {
    void *k = get_test_kernel_shiftedint_size_check();
    void *output_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_d, sizeof(size_t)));
    ASSERT_NE(nullptr, output_d);
    size_t output_h = 0;
    void *raw_args[1] = { &output_d };
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_h, output_d, sizeof(size_t), cudaMemcpyDeviceToHost));
    EXPECT_EQ(sizeof(nba::dev_offset_t), 2);
    EXPECT_EQ(sizeof(nba::dev_offset_t), output_h);
    ASSERT_EQ(cudaSuccess, cudaFree(output_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

TEST(CUDAStructTest, ShfitedIntValueCheck) {
    void *k = get_test_kernel_shiftedint_value_check();
    void *input_d;
    void *output_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&input_d, sizeof(nba::dev_offset_t)));
    ASSERT_NE(nullptr, input_d);
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_d, sizeof(uint64_t)));
    ASSERT_NE(nullptr, output_d);
    nba::dev_offset_t input_h = 165321;
    EXPECT_EQ(165320, input_h.as_value<uint64_t>());
    size_t output_h = 0;
    void *raw_args[2] = { &input_d, &output_d };
    ASSERT_EQ(cudaSuccess, cudaMemcpy(input_d, &input_h, sizeof(nba::dev_offset_t), cudaMemcpyHostToDevice));
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_h, output_d, sizeof(uint64_t), cudaMemcpyDeviceToHost));
    EXPECT_EQ(165320, output_h);
    ASSERT_EQ(cudaSuccess, cudaFree(input_d));
    ASSERT_EQ(cudaSuccess, cudaFree(output_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

TEST(CUDAStructTest, DatablockArgSizeAlignCheck) {
    void *k = get_test_kernel_dbarg_size_check();
    void *output_sizes_d;
    void *output_offsets_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_sizes_d, sizeof(size_t) * 2));
    ASSERT_NE(nullptr, output_sizes_d);
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_offsets_d, sizeof(size_t) * 2));
    ASSERT_NE(nullptr, output_offsets_d);
    size_t output_sizes_h[2] = { 0, 0 };
    size_t output_offsets_h[2] = { 0, 0 };
    void *raw_args[2] = { &output_sizes_d, &output_offsets_d };
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_sizes_h, output_sizes_d, sizeof(size_t) * 2, cudaMemcpyDeviceToHost));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_offsets_h, output_offsets_d, sizeof(size_t) * 2, cudaMemcpyDeviceToHost));
    EXPECT_EQ(sizeof(struct datablock_kernel_arg), output_sizes_h[0]);
    EXPECT_EQ(offsetof(struct datablock_kernel_arg, batches), output_offsets_h[0]);
    EXPECT_EQ(sizeof(struct datablock_batch_info), output_sizes_h[1]);
    EXPECT_EQ(offsetof(struct datablock_batch_info, item_offsets_in), output_offsets_h[1]);
    ASSERT_EQ(cudaSuccess, cudaFree(output_sizes_d));
    ASSERT_EQ(cudaSuccess, cudaFree(output_offsets_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

#else

TEST(CUDATest, Noop) {
    EXPECT_TRUE(1);
}

#endif

// vim: ts=8 sts=4 sw=4 et
<commit_msg>refs #27: Let CUDA test cases to run over all CUDA devices.<commit_after>#include <cstdint>
#include <cuda_runtime.h>
#include <nba/core/shiftedint.hh>
#include <nba/framework/datablock_shared.hh>
#include <gtest/gtest.h>
#include <nba/engines/cuda/test.hh>
#if 0
#require <engines/cuda/test.o>
#endif

using namespace std;
using namespace nba;

#ifdef USE_CUDA

static int getNumCUDADevices() {
    int count;
    cudaGetDeviceCount(&count);
    return count;
}

class CUDADeviceTest : public ::testing::TestWithParam<int> {
};

TEST_P(CUDADeviceTest, Initialization) {
    ASSERT_EQ(cudaSuccess, cudaSetDevice(GetParam()));
    ASSERT_EQ(cudaSuccess, cudaDeviceReset());
}

TEST_P(CUDADeviceTest, NoopKernel) {
    ASSERT_EQ(cudaSuccess, cudaSetDevice(GetParam()));
    void *k = get_test_kernel_noop();
    EXPECT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), nullptr, 0, 0));
    EXPECT_EQ(cudaSuccess, cudaDeviceSynchronize());
    ASSERT_EQ(cudaSuccess, cudaDeviceReset());
}

INSTANTIATE_TEST_CASE_P(PerDeviceDeviceTests, CUDADeviceTest, ::testing::Values(0, getNumCUDADevices() - 1));

class CUDAStructTest : public ::testing::TestWithParam<int> {
protected:
    virtual void SetUp() {
        cudaSetDevice(GetParam());
    }

    virtual void TearDown() {
        cudaDeviceReset();
    }
};

TEST_P(CUDAStructTest, ShfitedIntSizeCheck) {
    void *k = get_test_kernel_shiftedint_size_check();
    void *output_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_d, sizeof(size_t)));
    ASSERT_NE(nullptr, output_d);
    size_t output_h = 0;
    void *raw_args[1] = { &output_d };
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_h, output_d, sizeof(size_t), cudaMemcpyDeviceToHost));
    EXPECT_EQ(sizeof(nba::dev_offset_t), 2);
    EXPECT_EQ(sizeof(nba::dev_offset_t), output_h);
    ASSERT_EQ(cudaSuccess, cudaFree(output_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

TEST_P(CUDAStructTest, ShfitedIntValueCheck) {
    void *k = get_test_kernel_shiftedint_value_check();
    void *input_d;
    void *output_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&input_d, sizeof(nba::dev_offset_t)));
    ASSERT_NE(nullptr, input_d);
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_d, sizeof(uint64_t)));
    ASSERT_NE(nullptr, output_d);
    nba::dev_offset_t input_h = 165321;
    EXPECT_EQ(165320, input_h.as_value<uint64_t>());
    size_t output_h = 0;
    void *raw_args[2] = { &input_d, &output_d };
    ASSERT_EQ(cudaSuccess, cudaMemcpy(input_d, &input_h, sizeof(nba::dev_offset_t), cudaMemcpyHostToDevice));
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_h, output_d, sizeof(uint64_t), cudaMemcpyDeviceToHost));
    EXPECT_EQ(165320, output_h);
    ASSERT_EQ(cudaSuccess, cudaFree(input_d));
    ASSERT_EQ(cudaSuccess, cudaFree(output_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

TEST_P(CUDAStructTest, DatablockArgSizeAlignCheck) {
    void *k = get_test_kernel_dbarg_size_check();
    void *output_sizes_d;
    void *output_offsets_d;
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_sizes_d, sizeof(size_t) * 2));
    ASSERT_NE(nullptr, output_sizes_d);
    ASSERT_EQ(cudaSuccess, cudaMalloc(&output_offsets_d, sizeof(size_t) * 2));
    ASSERT_NE(nullptr, output_offsets_d);
    size_t output_sizes_h[2] = { 0, 0 };
    size_t output_offsets_h[2] = { 0, 0 };
    void *raw_args[2] = { &output_sizes_d, &output_offsets_d };
    ASSERT_EQ(cudaSuccess, cudaLaunchKernel(k, dim3(1), dim3(1), raw_args, 0, 0));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_sizes_h, output_sizes_d, sizeof(size_t) * 2, cudaMemcpyDeviceToHost));
    ASSERT_EQ(cudaSuccess, cudaMemcpy(&output_offsets_h, output_offsets_d, sizeof(size_t) * 2, cudaMemcpyDeviceToHost));
    EXPECT_EQ(sizeof(struct datablock_kernel_arg), output_sizes_h[0]);
    EXPECT_EQ(offsetof(struct datablock_kernel_arg, batches), output_offsets_h[0]);
    EXPECT_EQ(sizeof(struct datablock_batch_info), output_sizes_h[1]);
    EXPECT_EQ(offsetof(struct datablock_batch_info, item_offsets_in), output_offsets_h[1]);
    ASSERT_EQ(cudaSuccess, cudaFree(output_sizes_d));
    ASSERT_EQ(cudaSuccess, cudaFree(output_offsets_d));
    ASSERT_EQ(cudaSuccess, cudaDeviceSynchronize());
}

INSTANTIATE_TEST_CASE_P(PerDeviceStructTests, CUDAStructTest, ::testing::Values(0, getNumCUDADevices() - 1));

#else

TEST(CUDATest, Noop) {
    EXPECT_TRUE(1);
}

#endif

// vim: ts=8 sts=4 sw=4 et
<|endoftext|>


<commit_before>#include "catch.hpp"

#include <soa.hpp>

struct point
{
    float x;
    float y;
    float z;
};

TEST_CASE("", "[soa]")
{
    typedef helene::soa<
        point,
        helene::member_container<decltype(&point::x), &point::x>,
        helene::member_container<decltype(&point::y), &point::y>,
        helene::member_container<decltype(&point::z), &point::z>>
        mysoa;

    mysoa a;

    CHECK(a.size() == 0);

    SECTION("push back a value")
    {
        point p{1.1f, 2.2f, 3.3f};

        a.push_back(p);
        CHECK(a.size() == 1);

        SECTION("access first element by array access")
        {
            point pp = a[0];

            CHECK(pp.x == Approx(1.1f));
            CHECK(pp.y == Approx(2.2f));
            CHECK(pp.z == Approx(3.3f));
        }

        SECTION("access underlying buffer of x members")
        {
            auto x_data = a.data<decltype(&point::x), &point::x>();

            CHECK(*x_data == Approx(1.1f));
        }
    }
}

TEST_CASE("create element_proxy with some values", "[element_proxy]")
{
    typedef helene::element_proxy<
        point,
        helene::member_reference<decltype(&point::x), &point::x>,
        helene::member_reference<decltype(&point::y), &point::y>,
        helene::member_reference<decltype(&point::z), &point::z>>
        point_proxy;

    float x = 1.1f;
    float y = 2.1f;
    float z = 3.1f;

    point_proxy p(x, y, z);

    SECTION("implicitly convert to point")
    {
        point pp = p;

        CHECK(pp.x == Approx(1.1f));
        CHECK(pp.y == Approx(2.1f));
        CHECK(pp.z == Approx(3.1f));
    }

    SECTION("assign point to element_proxy")
    {
        point pp{2.2f, 3.3f, 4.4f};

        p = pp;

        CHECK(x == Approx(2.2f));
        CHECK(y == Approx(3.3f));
        CHECK(z == Approx(4.4f));
    }
}
<commit_msg>Add test. 	modified:   tests/test_soa.cpp<commit_after>#include "catch.hpp"

#include <soa.hpp>

struct point
{
    float x;
    float y;
    float z;
};

TEST_CASE("", "[soa]")
{
    typedef helene::soa<
        point,
        helene::member_container<decltype(&point::x), &point::x>,
        helene::member_container<decltype(&point::y), &point::y>,
        helene::member_container<decltype(&point::z), &point::z>>
        mysoa;

    mysoa a;

    CHECK(a.size() == 0);

    SECTION("push back values")
    {
        point p{1.1f, 2.2f, 3.3f};

        a.push_back(p);
        a.push_back({4.4f, 5.5f, 6.6f});
        REQUIRE(a.size() == 2);

        SECTION("access first element by array access")
        {
            point pp = a[0];

            CHECK(pp.x == Approx(1.1f));
            CHECK(pp.y == Approx(2.2f));
            CHECK(pp.z == Approx(3.3f));
        }

        SECTION("access underlying buffer of x members")
        {
            auto x_data = a.data<decltype(&point::x), &point::x>();

            CHECK(*x_data == Approx(1.1f));
            CHECK(x_data[1] == Approx(4.4f));
        }
    }
}

TEST_CASE("create element_proxy with some values", "[element_proxy]")
{
    typedef helene::element_proxy<
        point,
        helene::member_reference<decltype(&point::x), &point::x>,
        helene::member_reference<decltype(&point::y), &point::y>,
        helene::member_reference<decltype(&point::z), &point::z>>
        point_proxy;

    float x = 1.1f;
    float y = 2.1f;
    float z = 3.1f;

    point_proxy p(x, y, z);

    SECTION("implicitly convert to point")
    {
        point pp = p;

        CHECK(pp.x == Approx(1.1f));
        CHECK(pp.y == Approx(2.1f));
        CHECK(pp.z == Approx(3.1f));
    }

    SECTION("assign point to element_proxy")
    {
        point pp{2.2f, 3.3f, 4.4f};

        p = pp;

        CHECK(x == Approx(2.2f));
        CHECK(y == Approx(3.3f));
        CHECK(z == Approx(4.4f));
    }
}
<|endoftext|>


<commit_before>// clang-format off
// REQUIRES: lld

// Test various interesting cases for AST reconstruction.
// RUN: %clang_cl /Z7 /GS- /GR- /c /Fo%t.obj -- %s
// RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj
// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
// RUN:     %p/Inputs/ast-reconstruction.lldbinit 2>&1 | FileCheck %s

// Test trivial versions of each tag type.
class TrivialC {};
struct TrivialS {};
union TrivialU {};
enum TrivialE {TE_A};

// Test reconstruction of DeclContext hierarchies.
namespace A {
  namespace B {
    template<typename T>
    struct C {
      T ABCMember;
    };

    // Let's try a template specialization with a different implementation
    template<>
    struct C<void> {
      void *ABCSpecializationMember;
    };
  }

  // Let's make sure we can distinguish classes and namespaces.  Also let's try
  // a non-type template parameter.
  template<int N>
  struct C {
    class D {
      int ACDMember = 0;
      C<N - 1> *CPtr = nullptr;
    };
  };

  struct D {
    // Let's make a nested class with the same name as another nested class
    // elsewhere, and confirm that they appear in the right DeclContexts in
    // the AST.
    struct E {
      int ADDMember;
    };
  };
}

// Let's try an anonymous namespace.
namespace {
  template<typename T>
  struct Anonymous {
    int AnonymousMember;
    // And a nested class within an anonymous namespace
    struct D {
      int AnonymousDMember;
    };
  };
}

TrivialC TC;
TrivialS TS;
TrivialU TU;
TrivialE TE;

A::B::C<int> ABCInt;
A::B::C<float> ABCFloat;
A::B::C<void> ABCVoid;

A::C<0> AC0;
A::C<-1> ACNeg1;

A::C<0>::D AC0D;
A::C<-1>::D ACNeg1D;
A::D AD;
A::D::E ADE;

// FIXME: Anonymous namespaces aren't working correctly.
Anonymous<int> AnonInt;
Anonymous<A::B::C<void>> AnonABCVoid;
Anonymous<A::B::C<int>>::D AnonABCVoidD;

// FIXME: Enum size isn't being correctly determined.
// FIXME: Can't read memory for variable values.

// CHECK: (TrivialC) TC = {}
// CHECK: (TrivialS) TS = {}
// CHECK: (TrivialU) TU = {}
// CHECK: (TrivialE) TE = TE_A
// CHECK: (A::B::C<int>) ABCInt = (ABCMember = 0)
// CHECK: (A::B::C<float>) ABCFloat = (ABCMember = 0)
// CHECK: (A::B::C<void>) ABCVoid = (ABCSpecializationMember = 0x0000000000000000)
// CHECK: (A::C<0>) AC0 = {}
// CHECK: (A::C<-1>) ACNeg1 = {}
// CHECK: (A::C<0>::D) AC0D = (ACDMember = 0, CPtr = 0x0000000000000000)
// CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = 0, CPtr = 0x0000000000000000)
// CHECK: (A::D) AD = {}
// CHECK: (A::D::E) ADE = (ADDMember = 0)
// CHECK: Dumping clang ast for 1 modules.
// CHECK: TranslationUnitDecl {{.*}}
// CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
// CHECK: |-CXXRecordDecl {{.*}} struct TrivialS definition
// CHECK: |-CXXRecordDecl {{.*}} union TrivialU definition
// CHECK: |-EnumDecl {{.*}} TrivialE
// CHECK: | `-EnumConstantDecl {{.*}} TE_A 'TrivialE'
// CHECK: |-NamespaceDecl {{.*}} A
// CHECK: | |-NamespaceDecl {{.*}} B
// CHECK: | | |-CXXRecordDecl {{.*}} struct C<int> definition
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'int'
// CHECK: | | |-CXXRecordDecl {{.*}} struct C<float> definition
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> definition
// CHECK: | |   `-FieldDecl {{.*}} ABCSpecializationMember 'void *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<0> definition
// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
// CHECK: | |   |-FieldDecl {{.*}} ACDMember 'int'
// CHECK: | |   `-FieldDecl {{.*}} CPtr 'A::C<-1> *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<-1> definition
// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
// CHECK: | |   |-FieldDecl {{.*}} ACDMember 'int'
// CHECK: | |   `-FieldDecl {{.*}} CPtr 'A::C<-2> *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<-2>
// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
// CHECK: |   `-CXXRecordDecl {{.*}} struct E definition
// CHECK: |     `-FieldDecl {{.*}} ADDMember 'int'

int main(int argc, char **argv) {
  return 0;
}
<commit_msg>[NativePDB] Fix ast-reconstruction test on x86<commit_after>// clang-format off
// REQUIRES: lld

// Test various interesting cases for AST reconstruction.
// RUN: %clang_cl /Z7 /GS- /GR- /c /Fo%t.obj -- %s
// RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj
// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
// RUN:     %p/Inputs/ast-reconstruction.lldbinit 2>&1 | FileCheck %s

// Test trivial versions of each tag type.
class TrivialC {};
struct TrivialS {};
union TrivialU {};
enum TrivialE {TE_A};

// Test reconstruction of DeclContext hierarchies.
namespace A {
  namespace B {
    template<typename T>
    struct C {
      T ABCMember;
    };

    // Let's try a template specialization with a different implementation
    template<>
    struct C<void> {
      void *ABCSpecializationMember;
    };
  }

  // Let's make sure we can distinguish classes and namespaces.  Also let's try
  // a non-type template parameter.
  template<int N>
  struct C {
    class D {
      int ACDMember = 0;
      C<N - 1> *CPtr = nullptr;
    };
  };

  struct D {
    // Let's make a nested class with the same name as another nested class
    // elsewhere, and confirm that they appear in the right DeclContexts in
    // the AST.
    struct E {
      int ADDMember;
    };
  };
}

// Let's try an anonymous namespace.
namespace {
  template<typename T>
  struct Anonymous {
    int AnonymousMember;
    // And a nested class within an anonymous namespace
    struct D {
      int AnonymousDMember;
    };
  };
}

TrivialC TC;
TrivialS TS;
TrivialU TU;
TrivialE TE;

A::B::C<int> ABCInt;
A::B::C<float> ABCFloat;
A::B::C<void> ABCVoid;

A::C<0> AC0;
A::C<-1> ACNeg1;

A::C<0>::D AC0D;
A::C<-1>::D ACNeg1D;
A::D AD;
A::D::E ADE;

// FIXME: Anonymous namespaces aren't working correctly.
Anonymous<int> AnonInt;
Anonymous<A::B::C<void>> AnonABCVoid;
Anonymous<A::B::C<int>>::D AnonABCVoidD;

// FIXME: Enum size isn't being correctly determined.
// FIXME: Can't read memory for variable values.

// CHECK: (TrivialC) TC = {}
// CHECK: (TrivialS) TS = {}
// CHECK: (TrivialU) TU = {}
// CHECK: (TrivialE) TE = TE_A
// CHECK: (A::B::C<int>) ABCInt = (ABCMember = 0)
// CHECK: (A::B::C<float>) ABCFloat = (ABCMember = 0)
// CHECK: (A::B::C<void>) ABCVoid = (ABCSpecializationMember = 0x{{0+}})
// CHECK: (A::C<0>) AC0 = {}
// CHECK: (A::C<-1>) ACNeg1 = {}
// CHECK: (A::C<0>::D) AC0D = (ACDMember = 0, CPtr = 0x{{0+}})
// CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = 0, CPtr = 0x{{0+}})
// CHECK: (A::D) AD = {}
// CHECK: (A::D::E) ADE = (ADDMember = 0)
// CHECK: Dumping clang ast for 1 modules.
// CHECK: TranslationUnitDecl {{.*}}
// CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
// CHECK: |-CXXRecordDecl {{.*}} struct TrivialS definition
// CHECK: |-CXXRecordDecl {{.*}} union TrivialU definition
// CHECK: |-EnumDecl {{.*}} TrivialE
// CHECK: | `-EnumConstantDecl {{.*}} TE_A 'TrivialE'
// CHECK: |-NamespaceDecl {{.*}} A
// CHECK: | |-NamespaceDecl {{.*}} B
// CHECK: | | |-CXXRecordDecl {{.*}} struct C<int> definition
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'int'
// CHECK: | | |-CXXRecordDecl {{.*}} struct C<float> definition
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> definition
// CHECK: | |   `-FieldDecl {{.*}} ABCSpecializationMember 'void *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<0> definition
// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
// CHECK: | |   |-FieldDecl {{.*}} ACDMember 'int'
// CHECK: | |   `-FieldDecl {{.*}} CPtr 'A::C<-1> *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<-1> definition
// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
// CHECK: | |   |-FieldDecl {{.*}} ACDMember 'int'
// CHECK: | |   `-FieldDecl {{.*}} CPtr 'A::C<-2> *'
// CHECK: | |-CXXRecordDecl {{.*}} struct C<-2>
// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
// CHECK: |   `-CXXRecordDecl {{.*}} struct E definition
// CHECK: |     `-FieldDecl {{.*}} ADDMember 'int'

int main(int argc, char **argv) {
  return 0;
}
<|endoftext|>


<commit_before>#ifndef JARNGREIPR_CARBON_ALPHA
#define JARNGREIPR_CARBON_ALPHA
#include "Bead.hpp"
#include <algorithm>
#include <stdexcept>
#include <string>

namespace jarngreipr
{

/*! @brief carbon alpha 1 beads model */
template<typename traitsT>
class CarbonAlpha : public Bead<traitsT>
{
  public:

    typedef Bead<traitsT> base_type;
    typedef typename base_type::real_type real_type;
    typedef typename base_type::coordinate_type coordinate_type;
    typedef typename base_type::container_type container_type;
    typedef typename base_type::atom_type atom_type;

  public:

    CarbonAlpha() = default;
    CarbonAlpha(const residue_type& residue) : base_type(residue.atoms()){}
    CarbonAlpha(const container_type& atoms) : base_type(atoms){}
    ~CarbonAlpha() = default;

    coordinate_type position(const std::size_t i = 0) const override;
};

template<typename traitsT>
typename CarbonAlpha<traitsT>::coordinate_type
CarbonAlpha<traitsT>::position(const std::size_t i) const
{
    auto finder = [](const atom_type& a){return a.atom_name == "CA";};

    const std::size_t num_ca =
        std::count_if(atoms_.cbegin(), atoms_.cend(), finder);
    if(num_ca == 0)
        throw std::runtime_error("Ca: no c-alpha atom in this residue");
    else if(num_ca <= i)
        throw std::out_of_range(std::string("Ca: ") + std::to_string(i) +
                                std::string("-th Calpha does not exists"));

    const auto ca = std::find_if(atoms_.cbegin(), atoms_.cend(), finder);
    return ca->position;
}

}//jarngreipr
#endif /*JARNGREIPR_CARBON_ALPHA*/
<commit_msg>add impl of ctor<commit_after>#ifndef JARNGREIPR_CARBON_ALPHA
#define JARNGREIPR_CARBON_ALPHA
#include "Bead.hpp"
#include <algorithm>
#include <stdexcept>
#include <string>

namespace jarngreipr
{

/*! @brief carbon alpha 1 beads model */
template<typename traitsT>
class CarbonAlpha : public Bead<traitsT>
{
  public:

    typedef Bead<traitsT> base_type;
    typedef typename base_type::real_type real_type;
    typedef typename base_type::coordinate_type coordinate_type;
    typedef typename base_type::container_type container_type;
    typedef typename base_type::atom_type atom_type;
    typedef PDBResidue<traitsT> residue_type;

  public:

    CarbonAlpha() = default;
    CarbonAlpha(const residue_type& residue) : base_type(residue.atoms()){}
    CarbonAlpha(const container_type& atoms) : base_type(atoms){}
    CarbonAlpha(const residue_type& residue, const std::string& name)
        : base_type(residue.atoms(), name)
    {}
    CarbonAlpha(const container_type& atoms, const std::string& name)
        : base_type(atoms, name)
    {}
    ~CarbonAlpha() = default;

    coordinate_type position(const std::size_t i) const override;
};

template<typename traitsT>
typename CarbonAlpha<traitsT>::coordinate_type
CarbonAlpha<traitsT>::position(const std::size_t i) const
{
    auto finder = [](const atom_type& a){return a.atom_name == "CA";};

    const std::size_t num_ca =
        std::count_if(this->atoms_.cbegin(), this->atoms_.cend(), finder);
    if(num_ca == 0)
        throw std::runtime_error("Ca: no c-alpha atom in this residue");
    else if(num_ca <= i)
        throw std::out_of_range(std::string("Ca: ") + std::to_string(i) +
                                std::string("-th Calpha does not exists"));

    const auto ca = std::find_if(this->atoms_.cbegin(), this->atoms_.cend(), finder);
    return ca->position;
}

}//jarngreipr
#endif /*JARNGREIPR_CARBON_ALPHA*/
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <os>
#include <net/inet4>
#include <net/dhcp/dh4client.hpp>
#include <net/tcp.hpp>
#include <vector>

using namespace net;
using Connection_ptr = std::shared_ptr<TCP::Connection>;
std::unique_ptr<Inet4<VirtioNet>> inet;
std::shared_ptr<TCP::Connection> client;

std::string small, big, huge;
int S{150}, B{1500}, H{15000};
std::string TEST_STR {"1337"};

class Buffer {
public:
	size_t written;
	size_t read;
	char* data;
	const size_t size;

	inline Buffer(size_t length) :
		written(0), read(0), data(new char[length]), size(length)
	{}

	inline ~Buffer() {
		delete[] data;
	}

	std::string str() {
		return {data, size};
	}
};

void Service::start()
{
	for(int i = 0; i < S; i++) small += TEST_STR;
	for(int i = 0; i < B; i++) big += TEST_STR;
	for(int i = 0; i < H; i++) huge += TEST_STR;

	hw::Nic<VirtioNet>& eth0 = hw::Dev::eth<0,VirtioNet>();
  inet = std::make_unique<Inet4<VirtioNet>>(eth0);

  inet->network_config( {{ 10,0,0,42 }},      // IP
			{{ 255,255,255,0 }},  // Netmask
			{{ 10,0,0,1 }},       // Gateway
			{{ 8,8,8,8 }} );      // DNS

 	auto& tcp = inet->tcp();
 	tcp.set_buffer_limit(10);

	/*
		TEST: Send and receive small string.
	*/
	tcp.bind(1).onConnect([](Connection_ptr conn) {
		conn->onReceive([](Connection_ptr conn, bool) {
			printf("conn.read() == small: [%d]\n", conn->read() == small);
		});
		conn->write(small);
		conn->close();
	});
	/*
		TEST: 1 server should be bound.
	*/
	printf("tcp.openPorts() == 1: [%d]\n", tcp.openPorts() == 1);

	/*
		TEST: Send and receive big string.
	*/
	tcp.bind(2).onConnect([](Connection_ptr conn) {
		conn->onReceive([](Connection_ptr conn, bool) {
			auto response = conn->read();
			bool OK = (response == big);
			printf("conn.read() == big: [%d]\n", OK);
		});
		conn->write(big);
		conn->close();
	});

	/*
		TEST: Send and receive huge string.
	*/
	tcp.bind(3).onConnect([](Connection_ptr conn) {
		auto buffer = std::make_shared<Buffer>(huge.size());
		conn->onReceive([buffer](Connection_ptr conn, bool) {
			// if not all expected data is read
			if(buffer->read < huge.size())
				buffer->read += conn->read(buffer->data+buffer->read, conn->receive_buffer().data_size());
			printf("huge read: %u\n", buffer->read);
			//
			if(buffer->written < huge.size()) {
				buffer->written += conn->write(huge.data()+buffer->written, huge.size() - buffer->written);
				printf("huge written: %u\n", buffer->written);
			}
			//
			if(buffer->read == huge.size()) {
				int compare = strcmp(buffer->data, huge.data());
				printf("strcmp: %u\n", compare);
				printf("compare: buffer: %s - huge: %s \n", buffer->data+59900, huge.data()+59900);
				//printf("conn.read() == huge: [%d]\n", OK);
				conn->close();
			}
		});
		buffer->written += conn->write(huge.data()+buffer->size, huge.size() - buffer->written);
	});

}
<commit_msg>test: tcp - fixed huge string working<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <os>
#include <net/inet4>
#include <net/dhcp/dh4client.hpp>
#include <net/tcp.hpp>
#include <vector>

using namespace net;
using Connection_ptr = std::shared_ptr<TCP::Connection>;
std::unique_ptr<Inet4<VirtioNet>> inet;
std::shared_ptr<TCP::Connection> client;

std::string small, big, huge;
int S{150}, B{1500}, H{15000};
std::string TEST_STR {"1337"};

class Buffer {
public:
	size_t written;
	size_t read;
	char* data;
	const size_t size;

	inline Buffer(size_t length) :
		written(0), read(0), data(new char[length]), size(length)
	{}

	inline ~Buffer() {
		delete[] data;
	}

	std::string str() {
		return {data, size};
	}
};

void Service::start()
{
	for(int i = 0; i < S; i++) small += TEST_STR;
	for(int i = 0; i < B; i++) big += TEST_STR;
	for(int i = 0; i < H; i++) huge += TEST_STR;

	hw::Nic<VirtioNet>& eth0 = hw::Dev::eth<0,VirtioNet>();
  inet = std::make_unique<Inet4<VirtioNet>>(eth0);

  inet->network_config( {{ 10,0,0,42 }},      // IP
			{{ 255,255,255,0 }},  // Netmask
			{{ 10,0,0,1 }},       // Gateway
			{{ 8,8,8,8 }} );      // DNS

 	auto& tcp = inet->tcp();
 	tcp.set_buffer_limit(10);

	/*
		TEST: Send and receive small string.
	*/
	tcp.bind(1).onConnect([](Connection_ptr conn) {
		conn->onReceive([](Connection_ptr conn, bool) {
			printf("conn.read() == small: [%d]\n", conn->read() == small);
		});
		conn->write(small);
		conn->close();
	});
	/*
		TEST: 1 server should be bound.
	*/
	printf("tcp.openPorts() == 1: [%d]\n", tcp.openPorts() == 1);

	/*
		TEST: Send and receive big string.
	*/
	tcp.bind(2).onConnect([](Connection_ptr conn) {
		conn->onReceive([](Connection_ptr conn, bool) {
			auto response = conn->read();
			bool OK = (response == big);
			printf("conn.read() == big: [%d]\n", OK);
		});
		conn->write(big);
		conn->close();
	});

	/*
		TEST: Send and receive huge string.
	*/
	tcp.bind(3).onConnect([](Connection_ptr conn) {
		auto buffer = std::make_shared<Buffer>(huge.size());
		conn->onReceive([buffer](Connection_ptr conn, bool) {
			// if not all expected data is read
			if(buffer->read < huge.size())
				buffer->read += conn->read(buffer->data+buffer->read, conn->receive_buffer().data_size());
			printf("huge read: %u\n", buffer->read);
			//
			if(buffer->written < huge.size()) {
				buffer->written += conn->write(huge.data()+buffer->written, huge.size() - buffer->written);
				printf("huge written: %u\n", buffer->written);
			}
			//
			if(buffer->read == huge.size()) {
				//int compare = strcmp(buffer->data, huge.data());
				//bool OK = (compare == 0);
				bool OK = (buffer->str() == huge);
				printf("conn.read() == huge: [%d]\n", OK);
				conn->close();
			}
		});
		buffer->written += conn->write(huge.data()+buffer->written, huge.size() - buffer->written);
	});

}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <map>
#include <string>

#include <boost/algorithm/string/find.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <osquery/filesystem.h>
#include <osquery/sql.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"

namespace xp = boost::xpressive;

namespace osquery {
namespace tables {

const std::string kOSRelease = "/etc/os-release";
const std::string kRedhatRelease = "/etc/redhat-release";
const std::string kGentooRelease = "/etc/gentoo-release";

const std::map<std::string, std::string> kOSReleaseColumns = {
    {"NAME", "name"},
    {"VERSION", "version"},
    {"BUILD_ID", "build"},
    {"ID", "platform"},
    {"ID_LIKE", "platform_like"},
    {"VERSION_CODENAME", "codename"},
    {"VERSION_ID", "_id"},
};

QueryData genOSRelease() {
  // This will parse /etc/os-version according to the systemd manual.
  std::string content;
  if (!readFile(kOSRelease, content).ok()) {
    return {};
  }

  Row r;
  for (const auto& line : osquery::split(content, "\n")) {
    auto fields = osquery::split(line, "=", 1);
    if (fields.size() != 2) {
      continue;
    }

    auto column = std::ref(kOSReleaseColumns.at("VERSION_CODENAME"));
    if (kOSReleaseColumns.count(fields[0]) != 0) {
      column = std::ref(kOSReleaseColumns.at(fields[0]));
    } else if (fields[0].find("CODENAME") == std::string::npos) {
      // Some distros may attach/invent their own CODENAME field.
      continue;
    }

    r[column] = std::move(fields[1]);
    if (!r.at(column).empty() && r.at(column)[0] == '"') {
      // This is quote-enclosed string, make it pretty!
      r[column] = r[column].substr(1, r.at(column).size() - 2);
    }

    if (column.get() == "_id") {
      auto parts = osquery::split(r.at(column), ".", 2);
      switch (parts.size()) {
      case 3:
        r["patch"] = parts[2];
      case 2:
        r["minor"] = parts[1];
      case 1:
        r["major"] = parts[0];
        break;
      }
    }
  }

  return {r};
}

QueryData genOSVersion(QueryContext& context) {
  if (isReadable(kOSRelease)) {
    boost::system::error_code ec;
    // Funtoo has an empty os-release file.
    if (boost::filesystem::file_size(kOSRelease, ec) > 0) {
      return genOSRelease();
    }
  }

  Row r;
  std::string content;
  if (readFile(kRedhatRelease, content).ok()) {
    r["platform_like"] = "rhel";
  } else if (readFile(kGentooRelease, content).ok()) {
    r["platform_like"] = "gentoo";
  } else {
    return {};
  }

  boost::algorithm::trim_all(content);

  // This is an older version of a Redhat-based OS.
  auto rx = xp::sregex::compile(
      "(?P<name>[\\w+\\s]+) .* "
      "(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)\\.?(?P<patch>\\w+)?");
  xp::smatch matches;
  for (const auto& line : osquery::split(content, "\n")) {
    if (xp::regex_search(line, matches, rx)) {
      r["major"] = INTEGER(matches["major"]);
      r["minor"] = INTEGER(matches["minor"]);
      r["patch"] =
          (matches["patch"].length() > 0) ? INTEGER(matches["patch"]) : "0";
      r["name"] = matches["name"];
      break;
    }
  }

  r["version"] = content;

  // No build name.
  r["build"] = "";

  if (r["platform"] == "") {
    // Try to detect CentOS from the name. CentOS6 does not have all of the
    // keys we expect above that platform is typically extracted from.
    if (!boost::algorithm::ifind_first(r["name"], "centos").empty()) {
      r["platform"] = "centos";
    }
  }

  return {r};
}
}
}
<commit_msg>tables: Add default values for POSIX os_version (#3848)<commit_after>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <map>
#include <string>

#include <boost/algorithm/string/find.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <osquery/filesystem.h>
#include <osquery/sql.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"

namespace xp = boost::xpressive;

namespace osquery {
namespace tables {

const std::string kOSRelease = "/etc/os-release";
const std::string kRedhatRelease = "/etc/redhat-release";
const std::string kGentooRelease = "/etc/gentoo-release";

const std::map<std::string, std::string> kOSReleaseColumns = {
    {"NAME", "name"},
    {"VERSION", "version"},
    {"BUILD_ID", "build"},
    {"ID", "platform"},
    {"ID_LIKE", "platform_like"},
    {"VERSION_CODENAME", "codename"},
    {"VERSION_ID", "_id"},
};

QueryData genOSRelease(Row& r) {
  // This will parse /etc/os-version according to the systemd manual.
  std::string content;
  if (!readFile(kOSRelease, content).ok()) {
    return {r};
  }

  for (const auto& line : osquery::split(content, "\n")) {
    auto fields = osquery::split(line, "=", 1);
    if (fields.size() != 2) {
      continue;
    }

    auto column = std::ref(kOSReleaseColumns.at("VERSION_CODENAME"));
    if (kOSReleaseColumns.count(fields[0]) != 0) {
      column = std::ref(kOSReleaseColumns.at(fields[0]));
    } else if (fields[0].find("CODENAME") == std::string::npos) {
      // Some distros may attach/invent their own CODENAME field.
      continue;
    }

    r[column] = std::move(fields[1]);
    if (!r.at(column).empty() && r.at(column)[0] == '"') {
      // This is quote-enclosed string, make it pretty!
      r[column] = r[column].substr(1, r.at(column).size() - 2);
    }

    if (column.get() == "_id") {
      auto parts = osquery::split(r.at(column), ".", 2);
      switch (parts.size()) {
      case 3:
        r["patch"] = parts[2];
      case 2:
        r["minor"] = parts[1];
      case 1:
        r["major"] = parts[0];
        break;
      }
    }
  }

  return {r};
}

QueryData genOSVersion(QueryContext& context) {
  Row r;

  // Set defaults if we cannot determine the version.
  r["name"] = "Unknown";
  r["major"] = "0";
  r["minor"] = "0";
  r["patch"] = "0";
  r["platform"] = "posix";

  if (isReadable(kOSRelease)) {
    boost::system::error_code ec;
    // Funtoo has an empty os-release file.
    if (boost::filesystem::file_size(kOSRelease, ec) > 0) {
      return genOSRelease(r);
    }
  }

  std::string content;
  if (readFile(kRedhatRelease, content).ok()) {
    r["platform"] = "rhel";
    r["platform_like"] = "rhel";
  } else if (readFile(kGentooRelease, content).ok()) {
    r["platform"] = "gentoo";
    r["platform_like"] = "gentoo";
  } else {
    return {r};
  }

  boost::algorithm::trim_all(content);

  // This is an older version of a Redhat-based OS.
  auto rx = xp::sregex::compile(
      "(?P<name>[\\w+\\s]+) .* "
      "(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)\\.?(?P<patch>\\w+)?");
  xp::smatch matches;
  for (const auto& line : osquery::split(content, "\n")) {
    if (xp::regex_search(line, matches, rx)) {
      r["major"] = INTEGER(matches["major"]);
      r["minor"] = INTEGER(matches["minor"]);
      r["patch"] =
          (matches["patch"].length() > 0) ? INTEGER(matches["patch"]) : "0";
      r["name"] = matches["name"];
      break;
    }
  }

  r["version"] = content;

  // No build name.
  r["build"] = "";

  if (r["platform"] == "") {
    // Try to detect CentOS from the name. CentOS6 does not have all of the
    // keys we expect above that platform is typically extracted from.
    if (!boost::algorithm::ifind_first(r["name"], "centos").empty()) {
      r["platform"] = "centos";
    }
  }

  return {r};
}
}
}
<|endoftext|>


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

#include "base/basictypes.h"
#include "base/platform_thread.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::NotNull;

namespace {

class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
 public:
  MockAudioInputCallback() {}

  MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
  MOCK_METHOD2(OnError, void(AudioInputStream* stream, int error_code));
  MOCK_METHOD3(OnData, void(AudioInputStream* stream, const uint8* src,
                            uint32 size));
 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioInputCallback);
};

}

// ============================================================================
// Validate that the AudioManager::AUDIO_MOCK callbacks work.
TEST(FakeAudioInputTest, BasicCallbacks) {
  MockAudioInputCallback callback;
  EXPECT_CALL(callback, OnData(NotNull(), _, _)).Times(AtLeast(5));
  EXPECT_CALL(callback, OnError(NotNull(), _)).Times(Exactly(0));

  AudioManager* audio_man = AudioManager::GetAudioManager();
  ASSERT_TRUE(NULL != audio_man);
  // Ask for one recorded packet every 50ms.
  AudioInputStream* stream = audio_man->MakeAudioInputStream(
      AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 400));
  ASSERT_TRUE(NULL != stream);
  EXPECT_TRUE(stream->Open());
  stream->Start(&callback);
  PlatformThread::Sleep(340);  // Give sufficient time to receive 5 / 6 packets.
  stream->Stop();
  stream->Close();
}
<commit_msg>Mark FakeAudioInputTest.BasicCallbacks as flaky.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/platform_thread.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::NotNull;

namespace {

class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
 public:
  MockAudioInputCallback() {}

  MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
  MOCK_METHOD2(OnError, void(AudioInputStream* stream, int error_code));
  MOCK_METHOD3(OnData, void(AudioInputStream* stream, const uint8* src,
                            uint32 size));
 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioInputCallback);
};

}

// ============================================================================
// Validate that the AudioManager::AUDIO_MOCK callbacks work.
// Flaky, http://crbug.com/49497.
TEST(FakeAudioInputTest, FLAKY_BasicCallbacks) {
  MockAudioInputCallback callback;
  EXPECT_CALL(callback, OnData(NotNull(), _, _)).Times(AtLeast(5));
  EXPECT_CALL(callback, OnError(NotNull(), _)).Times(Exactly(0));

  AudioManager* audio_man = AudioManager::GetAudioManager();
  ASSERT_TRUE(NULL != audio_man);
  // Ask for one recorded packet every 50ms.
  AudioInputStream* stream = audio_man->MakeAudioInputStream(
      AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 400));
  ASSERT_TRUE(NULL != stream);
  EXPECT_TRUE(stream->Open());
  stream->Start(&callback);
  PlatformThread::Sleep(340);  // Give sufficient time to receive 5 / 6 packets.
  stream->Stop();
  stream->Close();
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CLIENT_COMMON_CLIENT_HPP_
#define JUBATUS_CLIENT_COMMON_CLIENT_HPP_

#include <stdint.h>
#include <map>
#include <string>
#include <jubatus/msgpack/rpc/client.h>

namespace jubatus {
namespace client {
namespace common {

class client {
 public:
  client(const std::string& host,
         uint64_t port,
         const std::string& name,
         unsigned int timeout_sec)
      : c_(host, port), name_(name) {
    c_.set_timeout(timeout_sec);
  }

  msgpack::rpc::client& get_client() {
    return c_;
  }

  std::string get_config() {
    msgpack::rpc::future f = c_.call("get_config", name_);
    return f.get<std::string>();
  }

  bool save(const std::string& id) {
    msgpack::rpc::future f = c_.call("save", name_, id);
    return f.get<bool>();
  }

  bool load(const std::string& id) {
    msgpack::rpc::future f = c_.call("load", name_, id);
    return f.get<bool>();
  }

  std::map<std::string, std::map<std::string, std::string> > get_status() {
    msgpack::rpc::future f = c_.call("get_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  std::map<std::string, std::map<std::string, std::string> >
      get_proxy_status() {
    msgpack::rpc::future f = c_.call("get_proxy_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  std::string get_name() const {
    return name_;
  }

  void set_name(const std::string& name) {
    name_ = name;
  }

 protected:
  msgpack::rpc::client c_;
  std::string name_;
};

}  // namespace common
}  // namespace client
}  // namespace jubatus

#endif  // JUBATUS_CLIENT_COMMON_CLIENT_HPP_
<commit_msg>add do_mix rpc<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CLIENT_COMMON_CLIENT_HPP_
#define JUBATUS_CLIENT_COMMON_CLIENT_HPP_

#include <stdint.h>
#include <map>
#include <string>
#include <jubatus/msgpack/rpc/client.h>

namespace jubatus {
namespace client {
namespace common {

class client {
 public:
  client(const std::string& host,
         uint64_t port,
         const std::string& name,
         unsigned int timeout_sec)
      : c_(host, port), name_(name) {
    c_.set_timeout(timeout_sec);
  }

  msgpack::rpc::client& get_client() {
    return c_;
  }

  std::string get_config() {
    msgpack::rpc::future f = c_.call("get_config", name_);
    return f.get<std::string>();
  }

  bool save(const std::string& id) {
    msgpack::rpc::future f = c_.call("save", name_, id);
    return f.get<bool>();
  }

  bool load(const std::string& id) {
    msgpack::rpc::future f = c_.call("load", name_, id);
    return f.get<bool>();
  }

  std::map<std::string, std::map<std::string, std::string> > get_status() {
    msgpack::rpc::future f = c_.call("get_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  bool do_mix() {
    msgpack::rpc::future f = c_.call("do_mix", name_);
    return f.get<bool>();
  }

  std::map<std::string, std::map<std::string, std::string> >
      get_proxy_status() {
    msgpack::rpc::future f = c_.call("get_proxy_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  std::string get_name() const {
    return name_;
  }

  void set_name(const std::string& name) {
    name_ = name;
  }

 protected:
  msgpack::rpc::client c_;
  std::string name_;
};

}  // namespace common
}  // namespace client
}  // namespace jubatus

#endif  // JUBATUS_CLIENT_COMMON_CLIENT_HPP_
<|endoftext|>


<commit_before>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qcombobox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <kdialog.h>
#include <klineedit.h>
#include <klocale.h>

#include "incsearchwidget.h"

IncSearchWidget::IncSearchWidget( QWidget *parent, const char *name )
    : QWidget( parent, name )
{
  setCaption( i18n( "Incremental Search" ) );

  QHBoxLayout *layout = new QHBoxLayout( this, 2, KDialog::spacingHint() );

  QLabel *label = new QLabel( i18n( "Search:" ), this );
  label->setAlignment( QLabel::AlignVCenter | QLabel::AlignRight );
  layout->addWidget( label );

  mSearchText = new KLineEdit( this );
  QWhatsThis::add( mSearchText, i18n( "The incremental search
Enter some text
  here will start the search for the contact, which matchs the search pattern best. The part of the contact, which will be used for matching, depends on the field selection." ) );
  layout->addWidget( mSearchText );

  mFieldCombo = new QComboBox( false, this );
  layout->addWidget( mFieldCombo );

  QToolTip::add( mFieldCombo, i18n( "Select Incremental Search Field" ) );
  QWhatsThis::add( mFieldCombo, i18n( "Here you can choose the field, which shall be used for incremental search." ) );

  resize( QSize(420, 50).expandedTo( sizeHint() ) );

  connect( mSearchText, SIGNAL( textChanged( const QString& ) ),
           SLOT( announceDoSearch() ) );
  connect( mSearchText, SIGNAL( returnPressed() ),
           SLOT( announceDoSearch() ) );
  connect( mFieldCombo, SIGNAL( activated( const QString& ) ),
           SLOT( announceDoSearch() ) );
  connect( mFieldCombo, SIGNAL( activated( const QString& ) ),
           SLOT( announceFieldChanged() ) );

  setFocusProxy( mSearchText );
}

IncSearchWidget::~IncSearchWidget()
{
}

void IncSearchWidget::announceDoSearch()
{
  emit doSearch( mSearchText->text() );
}

void IncSearchWidget::announceFieldChanged()
{
  emit fieldChanged();
}

void IncSearchWidget::setFields( const KABC::Field::List &list )
{
  mFieldCombo->clear();
  mFieldCombo->insertItem( i18n( "All Fields" ) );

  KABC::Field::List::ConstIterator it;
  for ( it = list.begin(); it != list.end(); ++it )
    mFieldCombo->insertItem( (*it)->label() );

  mFieldList = list;

  announceDoSearch();
  announceFieldChanged();
}

KABC::Field::List IncSearchWidget::fields() const
{
  return mFieldList;
}

KABC::Field *IncSearchWidget::currentField()const
{
  if ( mFieldCombo->currentItem() == -1 || mFieldCombo->currentItem() == 0 )
    return 0;  // for error or 'use all fields'
  else
    return mFieldList[ mFieldCombo->currentItem() - 1 ];
}

void IncSearchWidget::setCurrentItem( int pos )
{
  mFieldCombo->setCurrentItem( pos );
  announceFieldChanged();
}

int IncSearchWidget::currentItem() const
{
  return mFieldCombo->currentItem();
}

#include "incsearchwidget.moc"
<commit_msg>Fixed typo to get it compile SILENT<commit_after>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qcombobox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <kdialog.h>
#include <klineedit.h>
#include <klocale.h>

#include "incsearchwidget.h"

IncSearchWidget::IncSearchWidget( QWidget *parent, const char *name )
    : QWidget( parent, name )
{
  setCaption( i18n( "Incremental Search" ) );

  QHBoxLayout *layout = new QHBoxLayout( this, 2, KDialog::spacingHint() );

  QLabel *label = new QLabel( i18n( "Search:" ), this );
  label->setAlignment( QLabel::AlignVCenter | QLabel::AlignRight );
  layout->addWidget( label );

  mSearchText = new KLineEdit( this );
  QWhatsThis::add( mSearchText, i18n( "The incremental search
Enter some text here will start the search for the contact, which matchs the search pattern best. The part of the contact, which will be used for matching, depends on the field selection." ) );
  layout->addWidget( mSearchText );

  mFieldCombo = new QComboBox( false, this );
  layout->addWidget( mFieldCombo );

  QToolTip::add( mFieldCombo, i18n( "Select Incremental Search Field" ) );
  QWhatsThis::add( mFieldCombo, i18n( "Here you can choose the field, which shall be used for incremental search." ) );

  resize( QSize(420, 50).expandedTo( sizeHint() ) );

  connect( mSearchText, SIGNAL( textChanged( const QString& ) ),
           SLOT( announceDoSearch() ) );
  connect( mSearchText, SIGNAL( returnPressed() ),
           SLOT( announceDoSearch() ) );
  connect( mFieldCombo, SIGNAL( activated( const QString& ) ),
           SLOT( announceDoSearch() ) );
  connect( mFieldCombo, SIGNAL( activated( const QString& ) ),
           SLOT( announceFieldChanged() ) );

  setFocusProxy( mSearchText );
}

IncSearchWidget::~IncSearchWidget()
{
}

void IncSearchWidget::announceDoSearch()
{
  emit doSearch( mSearchText->text() );
}

void IncSearchWidget::announceFieldChanged()
{
  emit fieldChanged();
}

void IncSearchWidget::setFields( const KABC::Field::List &list )
{
  mFieldCombo->clear();
  mFieldCombo->insertItem( i18n( "All Fields" ) );

  KABC::Field::List::ConstIterator it;
  for ( it = list.begin(); it != list.end(); ++it )
    mFieldCombo->insertItem( (*it)->label() );

  mFieldList = list;

  announceDoSearch();
  announceFieldChanged();
}

KABC::Field::List IncSearchWidget::fields() const
{
  return mFieldList;
}

KABC::Field *IncSearchWidget::currentField()const
{
  if ( mFieldCombo->currentItem() == -1 || mFieldCombo->currentItem() == 0 )
    return 0;  // for error or 'use all fields'
  else
    return mFieldList[ mFieldCombo->currentItem() - 1 ];
}

void IncSearchWidget::setCurrentItem( int pos )
{
  mFieldCombo->setCurrentItem( pos );
  announceFieldChanged();
}

int IncSearchWidget::currentItem() const
{
  return mFieldCombo->currentItem();
}

#include "incsearchwidget.moc"
<|endoftext|>