<commit_before>/*************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    g_socket.cpp
* @version
* @brief
* @author   duye
* @date	    2014-2-16
* @note
*
*  2. 2014-06-21 duye move to gohoop
*  1. 2014-02-16 duye Created this file
*
*/
#include <g_sys.h>
#include <g_socket.h>
#include <net/if.h>

namespace gsys {

const struct in6_addr IN6ADDR_ANY = IN6ADDR_ANY_INIT;

SockAddr::SockAddr() : SockAddr(INADDR_ANY, 0) {}
SockAddr::SockAddr(const GUint32 ip, const GUint16 port)
{
    m_addrLen = sizeof(sockaddr_in);
    bzero(&m_addr, m_addrLen);
    m_addr.sin_family = AF_INET;
    m_addr.sin_port = htons(port);
    m_addr.sin_addr.s_addr = htonl(ip);
}

SockAddr::~SockAddr() {}

void SockAddr::setIP(const GUint32 ip)
{
    m_addr.sin_addr.s_addr = htonl(ip);
}

GUint32 SockAddr::ip()
{
    return ntohl(m_addr.sin_addr.s_addr);
}

GUint8* SockAddr::ipStr()
{
    return (GUint8*)inet_ntoa(m_addr.sin_addr);
}

void SockAddr::setPort(const GUint16 port)
{
    m_addr.sin_port = htons(port);
}

GUint16 SockAddr::port()
{
    return ntohs(m_addr.sin_port);
}

sockaddr_in& SockAddr::addr()
{
    return m_addr;
}

GUint16 SockAddr::addrLen() const
{
    return m_addrLen;
}

IPv6Addr::IPv6Addr()
{
    m_addrLen = sizeof(sockaddr_in6);
    bzero(&m_sockAddr, m_addrLen);
    m_sockAddr.sin6_family = AF_INET6;
    m_sockAddr.sin6_port = 0;
    m_sockAddr.sin6_addr = IN6ADDR_ANY;
}

IPv6Addr::IPv6Addr(const GUint8 ip[16], const GUint16 port)
{
    bzero(&m_sockAddr, sizeof(m_sockAddr));
    m_sockAddr.sin6_family = AF_INET6;
    m_sockAddr.sin6_port = htons(port);
    memcpy(m_sockAddr.sin6_addr.s6_addr, ip, 16);
}

IPv6Addr::~IPv6Addr() {}

GUint8* IPv6Addr::ip()
{
    return m_sockAddr.sin6_addr.s6_addr;
}

GUint16 IPv6Addr::port()
{
    return ntohs(m_sockAddr.sin6_port);
}

sockaddr_in6& IPv6Addr::addr()
{
    return m_sockAddr;
}

GUint16 IPv6Addr::addrLen() const
{
    return m_addrLen;
}

Socket::Socket() : m_sockfd(-1), m_isInit(false) {}
Socket::~Socket() { uninit(); }

GResult Socket::open(const NetProtocol& protocol, const std::string& if_name)
{
    GInt32 domain = AF_INET;
    GInt32 sock_type = -1;
    GInt32 sock_protocol = -1;
    switch (protocol)
    {
    	case G_IPPROTO_TCP:
    	{
            sock_protocol = IPPROTO_TCP;
            sock_type = SOCK_STREAM;
            break;
    	}
    	case G_IPPROTO_UDP:
    	{
    	    sock_protocol = IPPROTO_UDP;
    	    sock_type = SOCK_DGRAM;
    	    break;
    	}
    	case G_IPPROTO_SCTP:
    	{
    	    sock_protocol = IPPROTO_SCTP;
    	    setError("[warn]%s:argument protocol(%d) not support (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO; // not support
    	}
    	case G_IPPROTO_TIPC:
    	{
    	    //sock_protocol = IPPROTO_TIPC;
    	    setError("[warn]%s:argument protocol(%d) not support (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO; // not support
    	}
    	default:
        {
    	    setError("[error]%s:argument protocol(%d) invalid (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO;
        }
    }

    m_sockfd = ::socket(domain, sock_type, sock_protocol);
    if (m_sockfd < 0)
    {
    	setError("[error]%s: socket(%d, %d, %d) ret=%d invalid (%s:%d)\n",
    	    __FUNCTION__, domain, sock_type, sock_protocol, m_sockfd, __FILE__, __LINE__);
        return G_NO;
    }

    // init socket option
    initOption(if_name);
    m_isInit = true;
    return G_YES;
}

GResult Socket::close(const GInt32 how)
{
    // how = 0 : stop receive data
    // how = 1 : stop send data
    // how = 2 : both above way
    if (!m_isInit)
    {
    	return G_YES;
    }

    return (shutdown(m_sockfd, how) == 0 ? G_YES : G_NO);
}

GInt32 Socket::sockfd() const
{
    return m_sockfd;
}

GInt8* Socket::getError()
{
    return m_error;
}

GResult Socket::initOption(const std::string& if_name)
{
    GResult ret = G_YES;

    // setting specified interface
    struct ifreq interface;
    strncpy(interface.ifr_ifrn.ifrn_name, if_name.c_str(), if_name.length());
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char*)&interface, sizeof(interface)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = G_NO;
    }

    // set address reuse, address reuse flag, 1 reuse
    GInt32 reuse = 1;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = G_NO;
    }

    // send time limit, unit ms
    int send_time = 2000;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&send_time, sizeof(int)) == -1)
    {
    	 ret = false;
    }

    // receive time limit, unit ms
    int recv_time = 2000;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&recv_time, sizeof(int)) == -1)
    {
    	 ret = false;
    }

    // set send data buffer size
    GInt32 send_buf_size = 0xFFFF;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&send_buf_size, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // set receive data buffer size
    GInt32 recv_buf_size = 0xFFFF;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&recv_buf_size, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // don't copy data from system buffer to socket buffer when send data
    /*
    GInt32 is_copy = 0;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&is_copy, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // don't copy data from system buffer to GSocket buffer when receive data
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&is_copy, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }
    */

    // let data send completly after execute close GSocket
    /*
    struct STR_Linger
    {
    	GInt16 l_onoff;
    	GInt16 l_linger;
    };

    STR_Linger linger;
    linger.l_onoff = 1;		// 1. allow wait; 0. force close
    linger.l_linger = 1;	// the time of waiting unit s
    if (setsockopt(m_sockfd, SOL_GSocket, SO_LINGER, (const char*)&linger, sizeof(STR_Linger)) == -1)
    {
        ret = false;
    }
    */

    return ret;
}

void Socket::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

GInt64 Transfer::send(Socket& socket, const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return ::send(socket.sockfd(), data, len, flags);
}

GInt64 Transfer::sendmsg(Socket& socket, const struct msghdr* msg, const GInt32 flags)
{
    return ::sendmsg(socket.sockfd(), msg, flags);
}

GInt64 Transfer::sendto(Socket& socket, SockAddr& dst_addr, const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return ::sendto(socket.sockfd(), data, len, flags, (const struct sockaddr*)&dst_addr.addr(), dst_addr.addrLen());
}

GInt64 Transfer::recv(Socket& socket, GUint8* buffer, const GUint64 size, const GInt32 flags)
{
    return ::recv(socket.sockfd(), buffer, size, flags);
}

GInt64 Transfer::recvmsg(Socket& socket, struct msghdr* msg, const GInt32 flags)
{
    return ::recvmsg(socket.sockfd(), msg, flags);
}

GInt64 Transfer::recvfrom(Socket& socket, SockAddr& src_addr, GUint8* buffer, const GUint64 size, const GInt32 flags)
{
    GUint32 addr_len = src_addr.addLen();
    return ::recvfrom(socket.sockfd(), buffer, size, flags, (struct sockaddr*)&src_addr.addr(), &addr_len);
}

SocketServer::SocketServer() {}
SocketServer::SocketServer(const SocketInfo& socket_info)
{
    setSocketInfo(socket_info);
}

SocketServer::~SocketServer()
{
    close();
}

void SocketServer::setSocketInfo(const SocketInfo& socket_info)
{
    m_socketInfo = socket_info;
    m_addr.setIP(m_socketInfo.serverIP());
    m_addr.setPort(m_socketInfo.serverPort());
}

GResult SocketServer::bind()
{
    if (IS_NO(m_socket.open(m_socketInfo.protocol(), m_socketInfo.localIfName())))
    {
    	setError("[error]%s:Socket not init (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	return G_NO;
    }

    return ::bind(m_socket.sockfd(), (const struct sockaddr*)&m_addr.addr(), m_addr.addrLen()) < 0 ? G_NO : G_YES;
}

GResult SocketServer::listen(const GUint32 max_connect_num)
{
    return ::listen(m_socket.sockfd(), max_connect_num) == 0 ? G_YES : G_NO;
}

GInt32 SocketServer::accept(SockAddr& client_addr, const RecvMode& mode)
{
    GUint16 addr_len = client_addr.addrLen();
    if (mode == G_RECV_BLOCK)
    {
        return ::accept(m_socket.sockfd(), (struct sockaddr*)&client_addr.addr(), &addr_len);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return ::accept4(m_socket.sockfd(), (struct sockaddr*)&client_addr.addr(), &addr_len, SOCK_NONBLOCK);
    }

    return -1;
}

GInt64 SocketServer::recvfrom(SockAddr& client_addr, GUint8* buffer, const GUint64 size, const RecvMode& mode)
{
    if (mode == G_RECV_BLOCK)
    {
    	return Transfer::recvfrom(m_socket, client_addr, buffer, size);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return Transfer::recvfrom(m_socket, client_addr, buffer, size, MSG_DONTWAIT);
    }

    return -1;
}

GResult SocketServer::close()
{
    return m_socket.close();
}

GInt8* SocketServer::getError()
{
    return m_error;
}

void SocketServer::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

SocketClient::SocketClient(const SocketInfo& socket_info)
{
    setSocketInfo(socket_info);
}

SocketClient::~SocketClient()
{
    close();
}

void SocketClient::setSocketInfo(const SocketInfo& socket_info)
{
    m_socketInfo = socket_info;
    m_addr.setIP(m_socketInfo.serverIP());
    m_addr.setPort(m_socketInfo.serverPort());
}

GResult SocketClient::connect()
{
    if (IS_NO(m_socket.open(m_socketInfo.protocol(), m_socketInfo.localIfName())))
    {
    	setError("[error]%s:Socket not init (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	return G_NO;
    }

    return ::connect(m_socket.sockfd(), (const struct sockaddr*)&m_addr.addr(), m_addr.addrLen()) < 0 ? G_NO : G_YES;
}

GInt64 SocketClient::send(const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return Transfer::send(m_socket, data, len, flags);
}

GInt64 SocketClient::recv(GUint8* buffer, const GUint64 size, const RecvMode& mode)
{
    if (mode == G_RECV_BLOCK)
    {
    	return Transfer::recv(m_socket, buffer, size);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return Transfer::recv(m_socket, buffer, size, MSG_DONTWAIT);
    }

    return -1
}

GResult SocketClient::close()
{
    return m_socket.close();
}

GInt8* SocketClient::getError()
{
    return m_error;
}

void SocketClient::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

}
<commit_msg>Update g_socket.cpp<commit_after>/*************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    g_socket.cpp
* @version
* @brief
* @author   duye
* @date	    2014-2-16
* @note
*
*  2. 2014-06-21 duye move to gohoop
*  1. 2014-02-16 duye Created this file
*
*/
#include <g_sys.h>
#include <g_socket.h>
#include <net/if.h>

namespace gsys {

const struct in6_addr IN6ADDR_ANY = IN6ADDR_ANY_INIT;

SockAddr::SockAddr() : SockAddr(INADDR_ANY, 0) {}
SockAddr::SockAddr(const GUint32 ip, const GUint16 port)
{
    m_addrLen = sizeof(sockaddr_in);
    bzero(&m_addr, m_addrLen);
    m_addr.sin_family = AF_INET;
    m_addr.sin_port = htons(port);
    m_addr.sin_addr.s_addr = htonl(ip);
}

SockAddr::~SockAddr() {}

void SockAddr::setIP(const GUint32 ip)
{
    m_addr.sin_addr.s_addr = htonl(ip);
}

GUint32 SockAddr::ip()
{
    return ntohl(m_addr.sin_addr.s_addr);
}

GUint8* SockAddr::ipStr()
{
    return (GUint8*)inet_ntoa(m_addr.sin_addr);
}

void SockAddr::setPort(const GUint16 port)
{
    m_addr.sin_port = htons(port);
}

GUint16 SockAddr::port()
{
    return ntohs(m_addr.sin_port);
}

sockaddr_in& SockAddr::addr()
{
    return m_addr;
}

GUint16 SockAddr::addrLen() const
{
    return m_addrLen;
}

IPv6Addr::IPv6Addr()
{
    m_addrLen = sizeof(sockaddr_in6);
    bzero(&m_sockAddr, m_addrLen);
    m_sockAddr.sin6_family = AF_INET6;
    m_sockAddr.sin6_port = 0;
    m_sockAddr.sin6_addr = IN6ADDR_ANY;
}

IPv6Addr::IPv6Addr(const GUint8 ip[16], const GUint16 port)
{
    bzero(&m_sockAddr, sizeof(m_sockAddr));
    m_sockAddr.sin6_family = AF_INET6;
    m_sockAddr.sin6_port = htons(port);
    memcpy(m_sockAddr.sin6_addr.s6_addr, ip, 16);
}

IPv6Addr::~IPv6Addr() {}

GUint8* IPv6Addr::ip()
{
    return m_sockAddr.sin6_addr.s6_addr;
}

GUint16 IPv6Addr::port()
{
    return ntohs(m_sockAddr.sin6_port);
}

sockaddr_in6& IPv6Addr::addr()
{
    return m_sockAddr;
}

GUint16 IPv6Addr::addrLen() const
{
    return m_addrLen;
}

Socket::Socket() : m_sockfd(-1), m_isInit(false) {}
Socket::~Socket() { uninit(); }

GResult Socket::open(const NetProtocol& protocol, const std::string& if_name)
{
    GInt32 domain = AF_INET;
    GInt32 sock_type = -1;
    GInt32 sock_protocol = -1;
    switch (protocol)
    {
    	case G_IPPROTO_TCP:
    	{
            sock_protocol = IPPROTO_TCP;
            sock_type = SOCK_STREAM;
            break;
    	}
    	case G_IPPROTO_UDP:
    	{
    	    sock_protocol = IPPROTO_UDP;
    	    sock_type = SOCK_DGRAM;
    	    break;
    	}
    	case G_IPPROTO_SCTP:
    	{
    	    sock_protocol = IPPROTO_SCTP;
    	    setError("[warn]%s:argument protocol(%d) not support (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO; // not support
    	}
    	case G_IPPROTO_TIPC:
    	{
    	    //sock_protocol = IPPROTO_TIPC;
    	    setError("[warn]%s:argument protocol(%d) not support (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO; // not support
    	}
    	default:
        {
    	    setError("[error]%s:argument protocol(%d) invalid (%s:%d)\n", __FUNCTION__, protocol, __FILE__, __LINE__);
    	    return G_NO;
        }
    }

    m_sockfd = ::socket(domain, sock_type, sock_protocol);
    if (m_sockfd < 0)
    {
    	setError("[error]%s: socket(%d, %d, %d) ret=%d invalid (%s:%d)\n",
    	    __FUNCTION__, domain, sock_type, sock_protocol, m_sockfd, __FILE__, __LINE__);
        return G_NO;
    }

    // init socket option
    initOption(if_name);
    m_isInit = true;
    return G_YES;
}

GResult Socket::close(const GInt32 how)
{
    // how = 0 : stop receive data
    // how = 1 : stop send data
    // how = 2 : both above way
    if (!m_isInit)
    {
    	return G_YES;
    }

    return (shutdown(m_sockfd, how) == 0 ? G_YES : G_NO);
}

GInt32 Socket::sockfd() const
{
    return m_sockfd;
}

GInt8* Socket::getError()
{
    return m_error;
}

GResult Socket::initOption(const std::string& if_name)
{
    GResult ret = G_YES;

    // setting specified interface
    struct ifreq interface;
    strncpy(interface.ifr_ifrn.ifrn_name, if_name.c_str(), if_name.length());
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char*)&interface, sizeof(interface)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = G_NO;
    }

    // set address reuse, address reuse flag, 1 reuse
    GInt32 reuse = 1;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = G_NO;
    }

    // send time limit, unit ms
    int send_time = 2000;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&send_time, sizeof(int)) == -1)
    {
    	 ret = false;
    }

    // receive time limit, unit ms
    int recv_time = 2000;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&recv_time, sizeof(int)) == -1)
    {
    	 ret = false;
    }

    // set send data buffer size
    GInt32 send_buf_size = 0xFFFF;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&send_buf_size, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // set receive data buffer size
    GInt32 recv_buf_size = 0xFFFF;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&recv_buf_size, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // don't copy data from system buffer to socket buffer when send data
    /*
    GInt32 is_copy = 0;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&is_copy, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }

    // don't copy data from system buffer to GSocket buffer when receive data
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&is_copy, sizeof(GInt32)) == -1)
    {
    	setError("[warn]%s:setsockopt() failed (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	ret = false;
    }
    */

    // let data send completly after execute close GSocket
    /*
    struct STR_Linger
    {
    	GInt16 l_onoff;
    	GInt16 l_linger;
    };

    STR_Linger linger;
    linger.l_onoff = 1;		// 1. allow wait; 0. force close
    linger.l_linger = 1;	// the time of waiting unit s
    if (setsockopt(m_sockfd, SOL_GSocket, SO_LINGER, (const char*)&linger, sizeof(STR_Linger)) == -1)
    {
        ret = false;
    }
    */

    return ret;
}

void Socket::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

GInt64 Transfer::send(Socket& socket, const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return ::send(socket.sockfd(), data, len, flags);
}

GInt64 Transfer::sendmsg(Socket& socket, const struct msghdr* msg, const GInt32 flags)
{
    return ::sendmsg(socket.sockfd(), msg, flags);
}

GInt64 Transfer::sendto(Socket& socket, SockAddr& dst_addr, const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return ::sendto(socket.sockfd(), data, len, flags, (const struct sockaddr*)&dst_addr.addr(), dst_addr.addrLen());
}

GInt64 Transfer::recv(Socket& socket, GUint8* buffer, const GUint64 size, const GInt32 flags)
{
    return ::recv(socket.sockfd(), buffer, size, flags);
}

GInt64 Transfer::recvmsg(Socket& socket, struct msghdr* msg, const GInt32 flags)
{
    return ::recvmsg(socket.sockfd(), msg, flags);
}

GInt64 Transfer::recvfrom(Socket& socket, SockAddr& src_addr, GUint8* buffer, const GUint64 size, const GInt32 flags)
{
    GUint32 addr_len = src_addr.addLen();
    return ::recvfrom(socket.sockfd(), buffer, size, flags, (struct sockaddr*)&src_addr.addr(), &addr_len);
}

SocketServer::SocketServer() {}
SocketServer::SocketServer(const SocketInfo& socket_info)
{
    setSocketInfo(socket_info);
}

SocketServer::~SocketServer()
{
    close();
}

void SocketServer::setSocketInfo(const SocketInfo& socket_info)
{
    m_socketInfo = socket_info;
    m_addr.setIP(m_socketInfo.serverIP());
    m_addr.setPort(m_socketInfo.serverPort());
}

GResult SocketServer::bind()
{
    if (IS_NO(m_socket.open(m_socketInfo.protocol(), m_socketInfo.localIfName())))
    {
    	setError("[error]%s:Socket not init (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	return G_NO;
    }

    return ::bind(m_socket.sockfd(), (const struct sockaddr*)&m_addr.addr(), m_addr.addrLen()) < 0 ? G_NO : G_YES;
}

GResult SocketServer::listen(const GUint32 max_connect_num)
{
    return ::listen(m_socket.sockfd(), max_connect_num) == 0 ? G_YES : G_NO;
}

GInt32 SocketServer::accept(SockAddr& client_addr, const RecvMode& mode)
{
    GUint16 addr_len = client_addr.addrLen();
    if (mode == G_RECV_BLOCK)
    {
        return ::accept(m_socket.sockfd(), (struct sockaddr*)&client_addr.addr(), &addr_len);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return ::accept4(m_socket.sockfd(), (struct sockaddr*)&client_addr.addr(), &addr_len, SOCK_NONBLOCK);
    }

    return -1;
}

GInt64 SocketServer::recvfrom(SockAddr& client_addr, GUint8* buffer, const GUint64 size, const RecvMode& mode)
{
    if (mode == G_RECV_BLOCK)
    {
    	return Transfer::recvfrom(m_socket, client_addr, buffer, size);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return Transfer::recvfrom(m_socket, client_addr, buffer, size, MSG_DONTWAIT);
    }

    return -1;
}

GResult SocketServer::close()
{
    return m_socket.close();
}

GInt8* SocketServer::getError()
{
    return m_error;
}

void SocketServer::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

SocketClient::SocketClient(const SocketInfo& socket_info)
{
    setSocketInfo(socket_info);
}

SocketClient::~SocketClient()
{
    close();
}

void SocketClient::setSocketInfo(const SocketInfo& socket_info)
{
    m_socketInfo = socket_info;
    m_addr.setIP(m_socketInfo.serverIP());
    m_addr.setPort(m_socketInfo.serverPort());
}

GResult SocketClient::connect()
{
    if (IS_NO(m_socket.open(m_socketInfo.protocol(), m_socketInfo.localIfName())))
    {
    	setError("[error]%s:Socket not init (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
    	return G_NO;
    }

    return ::connect(m_socket.sockfd(), (const struct sockaddr*)&m_addr.addr(), m_addr.addrLen()) < 0 ? G_NO : G_YES;
}

GInt64 SocketClient::send(const GUint8* data, const GUint64 len, const GInt32 flags)
{
    return Transfer::send(m_socket, data, len, flags);
}

GInt64 SocketClient::recv(GUint8* buffer, const GUint64 size, const RecvMode& mode)
{
    if (mode == G_RECV_BLOCK)
    {
    	return Transfer::recv(m_socket, buffer, size);
    }
    else if (mode == G_RECV_UNBLOCK)
    {
    	return Transfer::recv(m_socket, buffer, size, MSG_DONTWAIT);
    }

    return -1
}

GResult SocketClient::close()
{
    return m_socket.close();
}

GInt8* SocketClient::getError()
{
    return m_error;
}

void SocketClient::setError(const GInt8* args, ...)
{
    System::pformat(m_error, G_ERROR_BUF_SIZE, args);
}

}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "OffscreenScene.h"

#include "SDLDisplayEngine.h"
#include "SceneNode.h"
#include "OGLTexture.h"

#include "../base/Exception.h"

#include <iostream>

using namespace boost;
using namespace std;

namespace avg {

OffscreenScene::OffscreenScene(Player * pPlayer, NodePtr pRootNode)
    : Scene(pPlayer, pRootNode)
{
    if (!pRootNode) {
        throw (Exception(AVG_ERR_XML_PARSE,
                "Root node of a scene tree needs to be a <scene> node."));
    }
    if (pRootNode->getID() == "") {
        throw (Exception(AVG_ERR_XML_PARSE,
                "Root node of a scene tree needs to have an id."));
    }
}

OffscreenScene::~OffscreenScene()
{
    glDeleteTextures(1, &m_TexID);
}

void OffscreenScene::initPlayback(DisplayEngine* pDisplayEngine,
        AudioEngine* pAudioEngine, TestHelper* pTestHelper)
{
    Scene::initPlayback(pDisplayEngine, pAudioEngine, pTestHelper);
    glGenTextures(1, &m_TexID);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glGenTextures()");
    glBindTexture(GL_TEXTURE_2D, m_TexID);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glBindTexture()");
    IntPoint size = getSize();
    // Mipmaps needed for FBO support on nVidia cards (!?)
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, size.x);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glTexImage2D()");

    unsigned multiSampleSamples = dynamic_cast<SDLDisplayEngine*>(pDisplayEngine)
            ->getOGLOptions().m_MultiSampleSamples;
    m_pFBO = FBOPtr(new FBO(size, R8G8B8X8, m_TexID, multiSampleSamples));
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}

void OffscreenScene::render()
{
    m_pFBO->activate();
    getDisplayEngine()->render(getRootNode(), true);
    m_pFBO->deactivate();
    m_pFBO->copyToDestTexture();
    OGLTexturePtr pTex(new OGLTexture(getSize(), B8G8R8X8,
            MaterialInfo(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true),
            getDisplayEngine(), PBO));
    pTex->setTexID(m_TexID);
    BitmapPtr pBmp = pTex->readbackBmp();
    pBmp->save(getID()+".png");
}

std::string OffscreenScene::getID() const
{
    return getRootNode()->getID();
}

bool OffscreenScene::isRunning() const
{
    return (m_pFBO != FBOPtr());
}

unsigned OffscreenScene::getTexID() const
{
    return m_pFBO->getTexture();
}

}
<commit_msg>Removed debugging code which was causing make distcheck to fail.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "OffscreenScene.h"

#include "SDLDisplayEngine.h"
#include "SceneNode.h"
#include "OGLTexture.h"

#include "../base/Exception.h"

#include <iostream>

using namespace boost;
using namespace std;

namespace avg {

OffscreenScene::OffscreenScene(Player * pPlayer, NodePtr pRootNode)
    : Scene(pPlayer, pRootNode)
{
    if (!pRootNode) {
        throw (Exception(AVG_ERR_XML_PARSE,
                "Root node of a scene tree needs to be a <scene> node."));
    }
    if (pRootNode->getID() == "") {
        throw (Exception(AVG_ERR_XML_PARSE,
                "Root node of a scene tree needs to have an id."));
    }
}

OffscreenScene::~OffscreenScene()
{
    glDeleteTextures(1, &m_TexID);
}

void OffscreenScene::initPlayback(DisplayEngine* pDisplayEngine,
        AudioEngine* pAudioEngine, TestHelper* pTestHelper)
{
    Scene::initPlayback(pDisplayEngine, pAudioEngine, pTestHelper);
    glGenTextures(1, &m_TexID);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glGenTextures()");
    glBindTexture(GL_TEXTURE_2D, m_TexID);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glBindTexture()");
    IntPoint size = getSize();
    // Mipmaps needed for FBO support on nVidia cards (!?)
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, size.x);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OffscreenScene::initPlayback: glTexImage2D()");

    unsigned multiSampleSamples = dynamic_cast<SDLDisplayEngine*>(pDisplayEngine)
            ->getOGLOptions().m_MultiSampleSamples;
    m_pFBO = FBOPtr(new FBO(size, R8G8B8X8, m_TexID, multiSampleSamples));
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}

void OffscreenScene::render()
{
    m_pFBO->activate();
    getDisplayEngine()->render(getRootNode(), true);
    m_pFBO->deactivate();
    m_pFBO->copyToDestTexture();
/*
    OGLTexturePtr pTex(new OGLTexture(getSize(), B8G8R8X8,
            MaterialInfo(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true),
            getDisplayEngine(), PBO));
    pTex->setTexID(m_TexID);
    BitmapPtr pBmp = pTex->readbackBmp();
    pBmp->save(getID()+".png");
*/
}

std::string OffscreenScene::getID() const
{
    return getRootNode()->getID();
}

bool OffscreenScene::isRunning() const
{
    return (m_pFBO != FBOPtr());
}

unsigned OffscreenScene::getTexID() const
{
    return m_pFBO->getTexture();
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fileidentifierconverter.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: sb $ $Date: 2001-06-06 07:32:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UCBHELPER_FILEIDENTIFIERCONVERTER_HXX_
#include <ucbhelper/fileidentifierconverter.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTPROVIDERINFO_HPP_
#include <com/sun/star/ucb/ContentProviderInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDERMANAGER_HPP_
#include <com/sun/star/ucb/XContentProviderManager.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XFILEIDENTIFIERCONVERTER_HPP_
#include <com/sun/star/ucb/XFileIdentifierConverter.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

using namespace com::sun;
using namespace com::sun::star;

namespace ucb {

//============================================================================
//
//  getLocalFileURL
//
//============================================================================

rtl::OUString
getLocalFileURL(
    uno::Reference< star::ucb::XContentProviderManager > const & rManager)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    OSL_ASSERT(rManager.is());

    static sal_Char const * const aBaseURLs[]
        = { "file:///", "vnd.sun.star.wfs:///" };
    sal_Int32 nMaxLocality = -1;
    rtl::OUString aMaxBaseURL;
    for (int i = 0; i < sizeof aBaseURLs / sizeof (sal_Char const *); ++i)
    {
        rtl::OUString aBaseURL(rtl::OUString::createFromAscii(aBaseURLs[i]));
        uno::Reference< star::ucb::XFileIdentifierConverter >
            xConverter(rManager->queryContentProvider(aBaseURL),
                       uno::UNO_QUERY);
        if (xConverter.is())
        {
            sal_Int32 nLocality
                = xConverter->getFileProviderLocality(aBaseURL);
            if (nLocality > nMaxLocality)
            {
                nMaxLocality = nLocality;
                aMaxBaseURL = aBaseURL;
            }
        }
    }
    return aMaxBaseURL;
}

//============================================================================
//
//  getFileURLFromSystemPath
//
//============================================================================

rtl::OUString
getFileURLFromSystemPath(
    uno::Reference< star::ucb::XContentProviderManager > const & rManager,
    rtl::OUString const & rBaseURL,
    rtl::OUString const & rSystemPath)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    OSL_ASSERT(rManager.is());

    uno::Reference< star::ucb::XFileIdentifierConverter >
        xConverter(rManager->queryContentProvider(rBaseURL), uno::UNO_QUERY);
    if (xConverter.is())
        return xConverter->getFileURLFromSystemPath(rBaseURL, rSystemPath);
    else
        return rtl::OUString();
}

//============================================================================
//
//  getSystemPathFromFileURL
//
//============================================================================

rtl::OUString
getSystemPathFromFileURL(
    uno::Reference< star::ucb::XContentProviderManager > const & rManager,
    rtl::OUString const & rURL)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    OSL_ASSERT(rManager.is());

    uno::Reference< star::ucb::XFileIdentifierConverter >
        xConverter(rManager->queryContentProvider(rURL), uno::UNO_QUERY);
    if (xConverter.is())
        return xConverter->getSystemPathFromFileURL(rURL);
    else
        return rtl::OUString();
}

}
<commit_msg>INTEGRATION: CWS sb33 (1.4.166); FILE MERGED 2005/06/27 16:12:36 sb 1.4.166.1: #i51181# Reduced getLocalFileURL to the minimum, so that it no longer instantiates the catch-all gnomevfs UCP for the nonexistent vnd.sun.star.wfs schema.<commit_after>/*************************************************************************
 *
 *  $RCSfile: fileidentifierconverter.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2005-07-07 10:55:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UCBHELPER_FILEIDENTIFIERCONVERTER_HXX_
#include <ucbhelper/fileidentifierconverter.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTPROVIDERINFO_HPP_
#include <com/sun/star/ucb/ContentProviderInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDERMANAGER_HPP_
#include <com/sun/star/ucb/XContentProviderManager.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XFILEIDENTIFIERCONVERTER_HPP_
#include <com/sun/star/ucb/XFileIdentifierConverter.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

using namespace com::sun;
using namespace com::sun::star;

namespace ucb {

//============================================================================
//
//  getLocalFileURL
//
//============================================================================

rtl::OUString
getLocalFileURL(
    uno::Reference< star::ucb::XContentProviderManager > const &)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    // If there were more file systems than just "file:///" (e.g., the obsolete
    // "vnd.sun.star.wfs:///"), this code should query all relevant UCPs for
    // their com.sun.star.ucb.XFileIdentifierConverter.getFileProviderLocality
    // and return the most local one:
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///"));
}

//============================================================================
//
//  getFileURLFromSystemPath
//
//============================================================================

rtl::OUString
getFileURLFromSystemPath(
    uno::Reference< star::ucb::XContentProviderManager > const & rManager,
    rtl::OUString const & rBaseURL,
    rtl::OUString const & rSystemPath)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    OSL_ASSERT(rManager.is());

    uno::Reference< star::ucb::XFileIdentifierConverter >
        xConverter(rManager->queryContentProvider(rBaseURL), uno::UNO_QUERY);
    if (xConverter.is())
        return xConverter->getFileURLFromSystemPath(rBaseURL, rSystemPath);
    else
        return rtl::OUString();
}

//============================================================================
//
//  getSystemPathFromFileURL
//
//============================================================================

rtl::OUString
getSystemPathFromFileURL(
    uno::Reference< star::ucb::XContentProviderManager > const & rManager,
    rtl::OUString const & rURL)
    SAL_THROW((com::sun::star::uno::RuntimeException))
{
    OSL_ASSERT(rManager.is());

    uno::Reference< star::ucb::XFileIdentifierConverter >
        xConverter(rManager->queryContentProvider(rURL), uno::UNO_QUERY);
    if (xConverter.is())
        return xConverter->getSystemPathFromFileURL(rURL);
    else
        return rtl::OUString();
}

}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <vector>
#include <cmath>

#include "ChSystemParallel.h"
#include "ChLcpSystemDescriptorParallel.h"

#include "utils/input_output.h"
#include "utils/generators.h"

using namespace chrono;

using std::cout;
using std::endl;

// =======================================================================
enum ProblemType {
	SETTLING,
	DROPPING
};

ProblemType problem = SETTLING;

// =======================================================================
// Global problem definitions

int threads = 8;

// Simulation parameters
double gravity = 9.81;
double time_step = 0.0001;
double time_settling_min = 1;
double time_settling_max = 5;
double time_dropping = 1;

int max_iteration = 20;

// Output
const char* data_folder = "../CRATER";
const char* checkpoint_file = "../CRATER/settled.dat";
double out_fps = 30;

// Parameters for the granular material
int        Id_g = 1;
double     r_g = 1e-3 / 2;
double     rho_g = 2500;
double     vol_g = (4.0/3) * PI * r_g * r_g * r_g;
double     mass_g = rho_g * vol_g;
ChVector<> inertia_g = 0.4 * mass_g * r_g * r_g * ChVector<>(1,1,1);

float      Y_g = 1e8;
float      mu_g = 0.3;
float      alpha_g = 0.1;

// Parameters for the falling ball
int        Id_b = 0;
double     R_b = 2.54e-2 / 2;
double     rho_b = 2000;
double     vol_b = (4.0/3) * PI * R_b * R_b * R_b;
double     mass_b = rho_b * vol_b;
ChVector<> inertia_b = 0.4 * mass_b * R_b * R_b * ChVector<>(1,1,1);

float      Y_b = 1e8;
float      mu_b = 0.3;
float      alpha_b = 0.1;

// Parameters for the containing bin
int        binId = -200;
double     hDimX = 4.5e-2;          // length in x direction
double     hDimY = 4.5e-2;          // depth in y direction
double     hDimZ = 7.5e-2;          // height in z direction
double     hThickness = 0.5e-2;     // wall thickness

float      Y_c = 2e6;
float      mu_c = 0.3;
float      alpha_c = 0.6;

// Height of the generator domain
double     genHeight = 8e-2;

// Drop height (above surface of settled granular material)
double h = 10e-2;

// =======================================================================

void AddWall(ChSharedBodyDEMPtr&  body,
             const ChVector<>&    loc,
             const ChVector<>&    dim)
{
	// Append to collision geometry
	body->GetCollisionModel()->AddBox(dim.x, dim.y, dim.z, loc);

	// Append to assets
	ChSharedPtr<ChBoxShape> box_shape = ChSharedPtr<ChAsset>(new ChBoxShape);
	box_shape->SetColor(ChColor(1, 0, 0));
	box_shape->Pos = loc;
	box_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
	box_shape->GetBoxGeometry().Size = dim;

	body->GetAssets().push_back(box_shape);
}

int CreateObjects(ChSystemParallel* system)
{
	// Create a material for the granular material
	ChSharedPtr<ChMaterialSurfaceDEM> mat_g;
	mat_g = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_g->SetYoungModulus(Y_g);
	mat_g->SetFriction(mu_g);
	mat_g->SetDissipationFactor(alpha_g);

	// Create a material for the container
	ChSharedPtr<ChMaterialSurfaceDEM> mat_c;
	mat_c = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_c->SetYoungModulus(Y_c);
	mat_c->SetFriction(mu_c);
	mat_c->SetDissipationFactor(alpha_c);

	// Create a mixture entirely made out of spheres
	utils::Generator gen(system);

	utils::MixtureIngredientPtr& m1 = gen.AddMixtureIngredient(utils::SPHERE, 1.0);
	m1->setDefaultMaterialDEM(mat_g);
	m1->setDefaultDensity(rho_g);
	m1->setDefaultSize(r_g);

	gen.setBodyIdentifier(Id_g);

	double r = 1.01 * r_g;

	gen.createObjectsBox(utils::POISSON_DISK,
	                     2 * r,
	                     ChVector<>(0, 0, r + genHeight/2),
	                     ChVector<>(hDimX - r, hDimY - r, genHeight/2));

	cout << "Number bodies generated: " << gen.getTotalNumBodies() << endl;

	// Create the containing bin
	ChSharedBodyDEMPtr bin(new ChBodyDEM(new ChCollisionModelParallel));

	bin->SetMaterialSurfaceDEM(mat_c);

	bin->SetIdentifier(binId);
	bin->SetMass(1);
	bin->SetPos(ChVector<>(0, 0, 0));
	bin->SetRot(ChQuaternion<>(1, 0, 0, 0));
	bin->SetCollide(true);
	bin->SetBodyFixed(true);

	bin->GetCollisionModel()->ClearModel();
	AddWall(bin, ChVector<>(0, 0, -hThickness), ChVector<>(hDimX, hDimY, hThickness));
	AddWall(bin, ChVector<>(-hDimX-hThickness, 0, hDimZ), ChVector<>(hThickness, hDimY, hDimZ));
	AddWall(bin, ChVector<>( hDimX+hThickness, 0, hDimZ), ChVector<>(hThickness, hDimY, hDimZ));
	AddWall(bin, ChVector<>(0, -hDimY-hThickness, hDimZ), ChVector<>(hDimX, hThickness, hDimZ));
	AddWall(bin, ChVector<>(0,  hDimY+hThickness, hDimZ), ChVector<>(hDimX, hThickness, hDimZ));
	bin->GetCollisionModel()->BuildModel();

	system->AddBody(bin);

	return gen.getTotalNumBodies();
}

// =======================================================================
// Create the falling ball such that its bottom point is at the specified
// height and its downward initial velocity has the specified magnitude.

void CreateFallingBall(ChSystemParallel* system, double z, double vz)
{
	// Create a material for the falling ball
	ChSharedPtr<ChMaterialSurfaceDEM> mat_b;
	mat_b = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_b->SetYoungModulus(1e8f);
	mat_b->SetFriction(0.4f);
	mat_b->SetDissipationFactor(0.1f);

	// Create the falling ball, but do not add it to the system
	ChSharedBodyDEMPtr ball(new ChBodyDEM(new ChCollisionModelParallel));

	ball->SetMaterialSurfaceDEM(mat_b);

	ball->SetIdentifier(Id_b);
	ball->SetMass(mass_b);
	ball->SetInertiaXX(inertia_b);
	ball->SetPos(ChVector<>(0, 0, z + R_b));
	ball->SetRot(ChQuaternion<>(1, 0, 0, 0));
	ball->SetPos_dt(ChVector<>(0, 0, -vz));
	ball->SetCollide(true);
	ball->SetBodyFixed(false);

	ball->GetCollisionModel()->ClearModel();
	ball->GetCollisionModel()->AddSphere(R_b);
	ball->GetCollisionModel()->BuildModel();

	ChSharedPtr<ChSphereShape> ball_shape = ChSharedPtr<ChAsset>(new ChSphereShape);
	ball_shape->SetColor(ChColor(0, 0, 1));
	ball_shape->GetSphereGeometry().rad = R_b;
	ball_shape->Pos = ChVector<>(0, 0, 0);
	ball_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
	ball->GetAssets().push_back(ball_shape);

	system->AddBody(ball);
}

// ========================================================================
// These utility functions find the height of the highest or lowest sphere
// in the granular mix, respectively.  We only look at bodies whith stricty
// positive identifiers.

double FindHighest(ChSystem* sys)
{
	double highest = 0;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0 && body->GetPos().z > highest)
			highest = body->GetPos().z;
	}
	return highest;
}

double FindLowest(ChSystem* sys)
{
	double lowest = 1000;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0 && body->GetPos().z < lowest)
			lowest = body->GetPos().z;
	}
	return lowest;
}

// ========================================================================
// This utility function returns true if all bodies in the granular mix
// have a linear velocity whose magnitude is below the specified value.

bool CheckSettled(ChSystem* sys, double threshold)
{
	double t2 = threshold * threshold;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0) {
			double vel2 = body->GetPos_dt().Length2();
			if (vel2 > t2)
				return false;
		}
	}

	return true;
}

// ========================================================================
int main(int argc, char* argv[])
{

	// Create system
	ChSystemParallelDEM* msystem = new ChSystemParallelDEM();

	// Set number of threads.
	int max_threads = msystem->GetParallelThreadNumber();
	if (threads > max_threads)
		threads = max_threads;
	msystem->SetParallelThreadNumber(threads);
	omp_set_num_threads(threads);

	// Set gravitational acceleration
	msystem->Set_G_acc(ChVector<>(0, 0, -gravity));

	// Edit system settings
	msystem->SetMaxiter(max_iteration);
	msystem->SetIterLCPmaxItersSpeed(max_iteration);
	msystem->SetTol(1e-3);
	msystem->SetTolSpeeds(1e-3);
	msystem->SetStep(time_step);

	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetMaxIteration(max_iteration);
	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetTolerance(0);
	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetContactRecoverySpeed(1);

	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->setBinsPerAxis(I3(10, 10, 10));
	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->setBodyPerBin(100, 50);

	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->ChangeNarrowphase(new ChCNarrowphaseR);

	// Depending on problem type:
	// - Select end simulation times
	// - Create granular material and container
	// - Create falling ball
	double time_end;

	if (problem == SETTLING) {
		time_end = time_settling_max;

		// Create containing bin and the granular material at randomized initial positions
		CreateObjects(msystem);
	} else {
		time_end = time_dropping;

		// Create the granular material bodies and the container from the checkpoint file.
		utils::ReadCheckpoint(msystem, checkpoint_file);

		// Create the falling ball just above the granular material with a velocity
		// given by free fall from the specified height and starting at rest.
		double z = FindHighest(msystem);
		double vz = std::sqrt(2 * gravity * h);
		CreateFallingBall(msystem, z, vz);
	}

	// Number of steps
	int num_steps = std::ceil(time_end / time_step);
	int out_steps = std::ceil((1 / time_step) / out_fps);

	// Zero velocity level for settling check (fraction of a grain radius per second)
	double zero_v = 0.1 * r_g;

	// Perform the simulation
	double time = 0;
	int sim_frame = 0;
	int out_frame = 0;
	int next_out_frame = 0;
	double exec_time = 0;

	while (time < time_end) {
		if (sim_frame == next_out_frame) {
			char filename[100];
			sprintf(filename, "%s/POVRAY/data_%03d.dat", data_folder, out_frame);
			utils::WriteShapesPovray(msystem, filename);

			cout << " --------------------------------- " << out_frame << "  " << time << "  " <<  endl;
			cout << "                                   " << FindLowest(msystem) << endl;
			cout << "                                   " << exec_time << endl;

			out_frame++;
			next_out_frame += out_steps;
		}

		if (problem == SETTLING && time > time_settling_min && CheckSettled(msystem, zero_v)) {
			cout << "Granular material settled...  time = " << time << endl;
			break;
		}

		msystem->DoStepDynamics(time_step);

		time += time_step;
		sim_frame++;
		exec_time += msystem->mtimer_step();
	}

	// Create a checkpoint from the last state
	if (problem == SETTLING)
		utils::WriteCheckpoint(msystem, checkpoint_file);

	// Final stats
	cout << "==================================" << endl;
	cout << "Number of bodies: " << msystem->Get_bodylist()->size() << endl;
	cout << "Lowest position: " << FindLowest(msystem) << endl;
	cout << "Simulation time: " << exec_time << endl;
	cout << "Number of threads: " << threads << endl;

	return 0;
}

<commit_msg>For efficiency, generate granules in layers.<commit_after>#include <stdio.h>
#include <vector>
#include <cmath>

#include "ChSystemParallel.h"
#include "ChLcpSystemDescriptorParallel.h"

#include "utils/input_output.h"
#include "utils/generators.h"

using namespace chrono;

using std::cout;
using std::endl;

// =======================================================================
enum ProblemType {
	SETTLING,
	DROPPING
};

ProblemType problem = SETTLING;

// =======================================================================
// Global problem definitions

int threads = 8;

// Simulation parameters
double gravity = 9.81;
double time_step = 0.0001;
double time_settling_min = 1;
double time_settling_max = 5;
double time_dropping = 1;

int max_iteration = 20;

// Output
const char* data_folder = "../CRATER";
const char* checkpoint_file = "../CRATER/settled.dat";
double out_fps = 30;

// Parameters for the granular material
int        Id_g = 1;
double     r_g = 1e-3 / 2;
double     rho_g = 2500;
double     vol_g = (4.0/3) * PI * r_g * r_g * r_g;
double     mass_g = rho_g * vol_g;
ChVector<> inertia_g = 0.4 * mass_g * r_g * r_g * ChVector<>(1,1,1);

float      Y_g = 1e8;
float      mu_g = 0.3;
float      alpha_g = 0.1;

// Parameters for the falling ball
int        Id_b = 0;
double     R_b = 2.54e-2 / 2;
double     rho_b = 2000;
double     vol_b = (4.0/3) * PI * R_b * R_b * R_b;
double     mass_b = rho_b * vol_b;
ChVector<> inertia_b = 0.4 * mass_b * R_b * R_b * ChVector<>(1,1,1);

float      Y_b = 1e8;
float      mu_b = 0.3;
float      alpha_b = 0.1;

// Parameters for the containing bin
int        binId = -200;
double     hDimX = 4.5e-2;          // length in x direction
double     hDimY = 4.5e-2;          // depth in y direction
double     hDimZ = 7.5e-2;          // height in z direction
double     hThickness = 0.5e-2;     // wall thickness

float      Y_c = 2e6;
float      mu_c = 0.3;
float      alpha_c = 0.6;

// Number of layers and height of one layer for generator domain
int        numLayers = 4;
double     layerHeight = 1e-2;

// Drop height (above surface of settled granular material)
double h = 10e-2;

// =======================================================================

void AddWall(ChSharedBodyDEMPtr&  body,
             const ChVector<>&    loc,
             const ChVector<>&    dim)
{
	// Append to collision geometry
	body->GetCollisionModel()->AddBox(dim.x, dim.y, dim.z, loc);

	// Append to assets
	ChSharedPtr<ChBoxShape> box_shape = ChSharedPtr<ChAsset>(new ChBoxShape);
	box_shape->SetColor(ChColor(1, 0, 0));
	box_shape->Pos = loc;
	box_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
	box_shape->GetBoxGeometry().Size = dim;

	body->GetAssets().push_back(box_shape);
}

int CreateObjects(ChSystemParallel* system)
{
	// Create a material for the granular material
	ChSharedPtr<ChMaterialSurfaceDEM> mat_g;
	mat_g = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_g->SetYoungModulus(Y_g);
	mat_g->SetFriction(mu_g);
	mat_g->SetDissipationFactor(alpha_g);

	// Create a material for the container
	ChSharedPtr<ChMaterialSurfaceDEM> mat_c;
	mat_c = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_c->SetYoungModulus(Y_c);
	mat_c->SetFriction(mu_c);
	mat_c->SetDissipationFactor(alpha_c);

	// Create a mixture entirely made out of spheres
	utils::Generator gen(system);

	utils::MixtureIngredientPtr& m1 = gen.AddMixtureIngredient(utils::SPHERE, 1.0);
	m1->setDefaultMaterialDEM(mat_g);
	m1->setDefaultDensity(rho_g);
	m1->setDefaultSize(r_g);

	gen.setBodyIdentifier(Id_g);

	double r = 1.01 * r_g;

	for (int i = 0; i < numLayers; i++) {
		double center = r + layerHeight / 2 + i * (r + layerHeight);
		gen.createObjectsBox(utils::POISSON_DISK,
		                     2 * r,
		                     ChVector<>(0, 0, center),
		                     ChVector<>(hDimX - r, hDimY - r, layerHeight/2));
		cout << "Layer " << i << "total bodies: " << gen.getTotalNumBodies() << endl;
	}

	// Create the containing bin
	ChSharedBodyDEMPtr bin(new ChBodyDEM(new ChCollisionModelParallel));

	bin->SetMaterialSurfaceDEM(mat_c);

	bin->SetIdentifier(binId);
	bin->SetMass(1);
	bin->SetPos(ChVector<>(0, 0, 0));
	bin->SetRot(ChQuaternion<>(1, 0, 0, 0));
	bin->SetCollide(true);
	bin->SetBodyFixed(true);

	bin->GetCollisionModel()->ClearModel();
	AddWall(bin, ChVector<>(0, 0, -hThickness), ChVector<>(hDimX, hDimY, hThickness));
	AddWall(bin, ChVector<>(-hDimX-hThickness, 0, hDimZ), ChVector<>(hThickness, hDimY, hDimZ));
	AddWall(bin, ChVector<>( hDimX+hThickness, 0, hDimZ), ChVector<>(hThickness, hDimY, hDimZ));
	AddWall(bin, ChVector<>(0, -hDimY-hThickness, hDimZ), ChVector<>(hDimX, hThickness, hDimZ));
	AddWall(bin, ChVector<>(0,  hDimY+hThickness, hDimZ), ChVector<>(hDimX, hThickness, hDimZ));
	bin->GetCollisionModel()->BuildModel();

	system->AddBody(bin);

	return gen.getTotalNumBodies();
}

// =======================================================================
// Create the falling ball such that its bottom point is at the specified
// height and its downward initial velocity has the specified magnitude.

void CreateFallingBall(ChSystemParallel* system, double z, double vz)
{
	// Create a material for the falling ball
	ChSharedPtr<ChMaterialSurfaceDEM> mat_b;
	mat_b = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM);
	mat_b->SetYoungModulus(1e8f);
	mat_b->SetFriction(0.4f);
	mat_b->SetDissipationFactor(0.1f);

	// Create the falling ball, but do not add it to the system
	ChSharedBodyDEMPtr ball(new ChBodyDEM(new ChCollisionModelParallel));

	ball->SetMaterialSurfaceDEM(mat_b);

	ball->SetIdentifier(Id_b);
	ball->SetMass(mass_b);
	ball->SetInertiaXX(inertia_b);
	ball->SetPos(ChVector<>(0, 0, z + R_b));
	ball->SetRot(ChQuaternion<>(1, 0, 0, 0));
	ball->SetPos_dt(ChVector<>(0, 0, -vz));
	ball->SetCollide(true);
	ball->SetBodyFixed(false);

	ball->GetCollisionModel()->ClearModel();
	ball->GetCollisionModel()->AddSphere(R_b);
	ball->GetCollisionModel()->BuildModel();

	ChSharedPtr<ChSphereShape> ball_shape = ChSharedPtr<ChAsset>(new ChSphereShape);
	ball_shape->SetColor(ChColor(0, 0, 1));
	ball_shape->GetSphereGeometry().rad = R_b;
	ball_shape->Pos = ChVector<>(0, 0, 0);
	ball_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
	ball->GetAssets().push_back(ball_shape);

	system->AddBody(ball);
}

// ========================================================================
// These utility functions find the height of the highest or lowest sphere
// in the granular mix, respectively.  We only look at bodies whith stricty
// positive identifiers.

double FindHighest(ChSystem* sys)
{
	double highest = 0;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0 && body->GetPos().z > highest)
			highest = body->GetPos().z;
	}
	return highest;
}

double FindLowest(ChSystem* sys)
{
	double lowest = 1000;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0 && body->GetPos().z < lowest)
			lowest = body->GetPos().z;
	}
	return lowest;
}

// ========================================================================
// This utility function returns true if all bodies in the granular mix
// have a linear velocity whose magnitude is below the specified value.

bool CheckSettled(ChSystem* sys, double threshold)
{
	double t2 = threshold * threshold;
	for (int i = 0; i < sys->Get_bodylist()->size(); ++i) {
		ChBody* body = (ChBody*) sys->Get_bodylist()->at(i);
		if (body->GetIdentifier() > 0) {
			double vel2 = body->GetPos_dt().Length2();
			if (vel2 > t2)
				return false;
		}
	}

	return true;
}

// ========================================================================
int main(int argc, char* argv[])
{

	// Create system
	ChSystemParallelDEM* msystem = new ChSystemParallelDEM();

	// Set number of threads.
	int max_threads = msystem->GetParallelThreadNumber();
	if (threads > max_threads)
		threads = max_threads;
	msystem->SetParallelThreadNumber(threads);
	omp_set_num_threads(threads);

	// Set gravitational acceleration
	msystem->Set_G_acc(ChVector<>(0, 0, -gravity));

	// Edit system settings
	msystem->SetMaxiter(max_iteration);
	msystem->SetIterLCPmaxItersSpeed(max_iteration);
	msystem->SetTol(1e-3);
	msystem->SetTolSpeeds(1e-3);
	msystem->SetStep(time_step);

	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetMaxIteration(max_iteration);
	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetTolerance(0);
	((ChLcpSolverParallelDEM*) msystem->GetLcpSolverSpeed())->SetContactRecoverySpeed(1);

	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->setBinsPerAxis(I3(10, 10, 10));
	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->setBodyPerBin(100, 50);

	((ChCollisionSystemParallel*) msystem->GetCollisionSystem())->ChangeNarrowphase(new ChCNarrowphaseR);

	// Depending on problem type:
	// - Select end simulation times
	// - Create granular material and container
	// - Create falling ball
	double time_end;

	if (problem == SETTLING) {
		time_end = time_settling_max;

		// Create containing bin and the granular material at randomized initial positions
		CreateObjects(msystem);
	} else {
		time_end = time_dropping;

		// Create the granular material bodies and the container from the checkpoint file.
		utils::ReadCheckpoint(msystem, checkpoint_file);

		// Create the falling ball just above the granular material with a velocity
		// given by free fall from the specified height and starting at rest.
		double z = FindHighest(msystem);
		double vz = std::sqrt(2 * gravity * h);
		CreateFallingBall(msystem, z, vz);
	}

	// Number of steps
	int num_steps = std::ceil(time_end / time_step);
	int out_steps = std::ceil((1 / time_step) / out_fps);

	// Zero velocity level for settling check (fraction of a grain radius per second)
	double zero_v = 0.1 * r_g;

	// Perform the simulation
	double time = 0;
	int sim_frame = 0;
	int out_frame = 0;
	int next_out_frame = 0;
	double exec_time = 0;

	while (time < time_end) {
		if (sim_frame == next_out_frame) {
			char filename[100];
			sprintf(filename, "%s/POVRAY/data_%03d.dat", data_folder, out_frame);
			utils::WriteShapesPovray(msystem, filename);

			cout << " --------------------------------- " << out_frame << "  " << time << "  " <<  endl;
			cout << "                                   " << FindLowest(msystem) << endl;
			cout << "                                   " << exec_time << endl;

			out_frame++;
			next_out_frame += out_steps;
		}

		if (problem == SETTLING && time > time_settling_min && CheckSettled(msystem, zero_v)) {
			cout << "Granular material settled...  time = " << time << endl;
			break;
		}

		msystem->DoStepDynamics(time_step);

		time += time_step;
		sim_frame++;
		exec_time += msystem->mtimer_step();
	}

	// Create a checkpoint from the last state
	if (problem == SETTLING)
		utils::WriteCheckpoint(msystem, checkpoint_file);

	// Final stats
	cout << "==================================" << endl;
	cout << "Number of bodies: " << msystem->Get_bodylist()->size() << endl;
	cout << "Lowest position: " << FindLowest(msystem) << endl;
	cout << "Simulation time: " << exec_time << endl;
	cout << "Number of threads: " << threads << endl;

	return 0;
}

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep12/call_omi_setup.C $                     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2020                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file    call_omi_setup.C
 *
 *  Contains the wrapper for Istep 12.6
 *      exp_omi_setup
 *      p10_omi_setup
 */

#include    <stdint.h>

#include    <trace/interface.H>
#include    <initservice/taskargs.H>
#include    <errl/errlentry.H>

#include    <isteps/hwpisteperror.H>
#include    <errl/errludtarget.H>

#include    <initservice/isteps_trace.H>
#include    <istepHelperFuncs.H>          // captureError

// Fapi Support
#include    <config.h>
#include    <fapi2/plat_hwp_invoker.H>

// HWP
#include    <exp_omi_setup.H>

using   namespace   ISTEP;
using   namespace   ISTEP_ERROR;
using   namespace   ERRORLOG;
using   namespace   TARGETING;
using   namespace   ISTEPS_TRACE;

namespace ISTEP_12
{
void* call_omi_setup (void *io_pArgs)
{
    IStepError l_StepError;
    errlHndl_t l_err = nullptr;
    TRACFCOMP( g_trac_isteps_trace, "call_omi_setup entry" );

    do
    {
        // 12.6.a exp_omi_setup.C
        //        - Set any register (via I2C) on the Explorer before OMI is
        //          trained
        TargetHandleList l_ocmbTargetList;
        getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
        TRACFCOMP(g_trac_isteps_trace,
                "call_omi_setup: %d OCMBs found",
                l_ocmbTargetList.size());

        for (const auto & l_ocmb_target : l_ocmbTargetList)
        {
            //  call the HWP with each target
            fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
                (l_ocmb_target);

            TRACFCOMP(g_trac_isteps_trace,
                    "exp_omi_setup HWP target HUID 0x%.08x",
                    get_huid(l_ocmb_target));

            FAPI_INVOKE_HWP(l_err, exp_omi_setup, l_fapi_ocmb_target);

            //  process return code
            if ( l_err )
            {
                TRACFCOMP(g_trac_isteps_trace,
                    "ERROR : call exp_omi_setup HWP: failed on target 0x%08X. "
                    TRACE_ERR_FMT,
                    get_huid(l_ocmb_target),
                    TRACE_ERR_ARGS(l_err));

                // Capture error
                captureError(l_err, l_StepError, HWPF_COMP_ID, l_ocmb_target);
            }
        }

        // Do not continue if an error was encountered
        if(!l_StepError.isNull())
        {
            TRACFCOMP( g_trac_isteps_trace,
                INFO_MRK "call_omi_setup exited early because exp_omi_setup "
                "had failures" );
            break;
        }

        // 12.6.b p10_omi_setup.C
        //        - File does not currently exist
        //        - TODO: RTC 248244

    } while (0);

    TRACFCOMP(g_trac_isteps_trace, "call_omi_setup exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_StepError.getErrorHandle();
}

};
<commit_msg>Parellelize omi_setup istep<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep12/call_omi_setup.C $                     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2020                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file    call_omi_setup.C
 *
 *  Contains the wrapper for Istep 12.6
 *      exp_omi_setup
 *      p10_omi_setup
 */

#include    <stdint.h>

#include    <trace/interface.H>
#include    <initservice/taskargs.H>
#include    <errl/errlentry.H>
#include    <util/threadpool.H>
#include    <sys/task.h>
#include    <initservice/istepdispatcherif.H>

#include    <isteps/hwpisteperror.H>
#include    <errl/errludtarget.H>

#include    <initservice/isteps_trace.H>
#include    <istepHelperFuncs.H>          // captureError

// Fapi Support
#include    <config.h>
#include    <fapi2/plat_hwp_invoker.H>

// HWP
#include    <exp_omi_setup.H>

using   namespace   ISTEP;
using   namespace   ISTEP_ERROR;
using   namespace   ERRORLOG;
using   namespace   TARGETING;
using   namespace   ISTEPS_TRACE;

namespace ISTEP_12
{
//
// @brief Mutex to prevent threads from adding details to the step
//        error log at the same time.
mutex_t g_stepErrorMutex = MUTEX_INITIALIZER;

/*******************************************************************************
 * @brief base work item class for isteps (used by thread pool)
 */
class IStepWorkItem
{
    public:
        virtual ~IStepWorkItem(){}
        virtual void operator()() = 0;
};

/*******************************************************************************
 * @brief Ocmb specific work item class
 */
class OcmbWorkItem: public IStepWorkItem
{
    private:
        IStepError* iv_pStepError;
        const TARGETING::Target* iv_pOcmb;

    public:
        /**
         * @brief task function, called by threadpool to run the HWP on the
         *        target
         */
         void operator()();

        /**
         * @brief ctor
         *
         * @param[in] i_Ocmb target Ocmb to operate on
         * @param[in] i_istepError error accumulator for this istep
         */
        OcmbWorkItem(const TARGETING::Target& i_Ocmb,
                       IStepError& i_stepError):
            iv_pStepError(&i_stepError),
            iv_pOcmb(&i_Ocmb) {}

        // delete default copy/move constructors and operators
        OcmbWorkItem() = delete;
        OcmbWorkItem(const OcmbWorkItem& ) = delete;
        OcmbWorkItem& operator=(const OcmbWorkItem& ) = delete;
        OcmbWorkItem(OcmbWorkItem&&) = delete;
        OcmbWorkItem& operator=(OcmbWorkItem&&) = delete;

        /**
         * @brief destructor
         */
        ~OcmbWorkItem(){};
};

//******************************************************************************
void OcmbWorkItem::operator()()
{
    errlHndl_t l_err = nullptr;

    // reset watchdog for each ocmb as this function can be very slow
    INITSERVICE::sendProgressCode();

    //  call the HWP with each target
    fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
      (iv_pOcmb);

    TRACFCOMP(g_trac_isteps_trace,
              "exp_omi_setup HWP target HUID 0x%.08x",
              get_huid(iv_pOcmb));

    FAPI_INVOKE_HWP(l_err, exp_omi_setup, l_fapi_ocmb_target);

    //  process return code
    if ( l_err )
    {
        TRACFCOMP(g_trac_isteps_trace,
                  "ERROR : call exp_omi_setup HWP: failed on target 0x%08X. "
                  TRACE_ERR_FMT,
                  get_huid(iv_pOcmb),
                  TRACE_ERR_ARGS(l_err));

        //addErrorDetails may not be thread-safe.  Protect with mutex.
        mutex_lock(&g_stepErrorMutex);

        // Capture error
        captureError(l_err, *iv_pStepError, HWPF_COMP_ID, iv_pOcmb);

        mutex_unlock(&g_stepErrorMutex);
    }
    else
    {
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "SUCCESS running exp_omi_setup HWP on target HUID %.8X.",
                   TARGETING::get_huid(iv_pOcmb));
    }
}

void* call_omi_setup (void *io_pArgs)
{
    IStepError l_StepError;
    errlHndl_t l_err = nullptr;
    TRACFCOMP( g_trac_isteps_trace, "call_omi_setup entry" );
    Util::ThreadPool<IStepWorkItem> threadpool;
    constexpr size_t MAX_OCMB_THREADS = 4;
    uint32_t l_numThreads = 0;

    do
    {
        // 12.6.a exp_omi_setup.C
        //        - Set any register (via I2C) on the Explorer before OMI is
        //          trained
        TargetHandleList l_ocmbTargetList;
        getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
        TRACFCOMP(g_trac_isteps_trace,
                "call_omi_setup: %d OCMBs found",
                l_ocmbTargetList.size());

        for (const auto & l_ocmb_target : l_ocmbTargetList)
        {
            //  Create a new workitem from this membuf and feed it to the
            //  thread pool for processing.  Thread pool handles workitem
            //  cleanup.
            threadpool.insert(new OcmbWorkItem(*l_ocmb_target,
                                               l_StepError));
        }

        //Don't create more threads than we have targets
        size_t l_numTargets = l_ocmbTargetList.size();
        l_numThreads = std::min(MAX_OCMB_THREADS, l_numTargets);

        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                  "Starting %llu thread(s) to handle %llu OCMB target(s)",
                   l_numThreads, l_numTargets);

        //Set the number of threads to use in the threadpool
        Util::ThreadPoolManager::setThreadCount(l_numThreads);

        //create and start worker threads
        threadpool.start();

        //wait for all workitems to complete, then clean up all threads.
        l_err = threadpool.shutdown();
        if(l_err)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      ERR_MRK"call_omi_setup: thread pool returned an error"
                      TRACE_ERR_FMT,
                      TRACE_ERR_ARGS(l_err));

            //addErrorDetails may not be thread-safe.  Protect with mutex.
            mutex_lock(&g_stepErrorMutex);

            // Capture error
            captureError(l_err, l_StepError, HWPF_COMP_ID, nullptr);

            mutex_unlock(&g_stepErrorMutex);
        }

        // Do not continue if an error was encountered
        if(!l_StepError.isNull())
        {
            TRACFCOMP( g_trac_isteps_trace,
                INFO_MRK "call_omi_setup exited early because exp_omi_setup "
                "had failures" );
            break;
        }

        // 12.6.b p10_omi_setup.C
        //        - File does not currently exist
        //        - TODO: RTC 248244

    } while (0);

    TRACFCOMP(g_trac_isteps_trace, "call_omi_setup exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_StepError.getErrorHandle();
}

};
<|endoftext|>


<commit_before>#include "IdDictionary.hpp"

#include <ros/console.h>

using namespace std;

IdDictionary::IdDictionary()
{
	translated = false;
}

bool IdDictionary::contains(int n)
{
	mutex.lock();

	for (vector<int>::iterator it = ids.begin(); it != ids.end(); it++) {
		if (*it == n) {
			mutex.unlock();
			return true;
		}
	}

	mutex.unlock();
	return false;
}

void IdDictionary::insert(int n)
{
	if (contains(n)) {
		return;
	}

	if (translated) {
		ROS_ERROR("insert: Ids already translated!");
	}

	mutex.lock();

	ROS_DEBUG("Inserted id %d", n);
	ids.push_back(n);

	mutex.unlock();
}

int IdDictionary::size()
{
	return ids.size();
}

void IdDictionary::translateIds()
{
	if (translated) {
		return;
	}

	mutex.lock();

	ROS_DEBUG("Translating dictionary with %d ids", size());

	translated = true;

	std::sort(ids.begin(), ids.end());
	int id = 0;

	for (vector<int>::iterator it = ids.begin(); it != ids.end(); it++, id++) {
		backward[id] = *it;
		forward[*it] = id;
	}

	mutex.unlock();
}

bool IdDictionary::isTranslated()
{
	return translated;
}

int IdDictionary::getForward(int n)
{
	if (!translated) {
		ROS_ERROR("getForward: Ids not translated!");
	}

	mutex.lock();

	if (forward.count(n)) {
		mutex.unlock();
		return forward[n];
	} else {
		ROS_ERROR("getForward: Unknown id %d", n);
		mutex.unlock();
		return -1;
	}
}

int IdDictionary::getBackward(int n)
{
	if (!translated) {
		ROS_ERROR("getBackward: Ids not translated!");
	}

	mutex.lock();

	if (backward.count(n)) {
		mutex.unlock();
		return backward[n];
	} else {
		ROS_ERROR("getBackward: Unknown id %d", n);
		mutex.unlock();
		return -1;
	}
}<commit_msg>Changed returning<commit_after>#include "IdDictionary.hpp"

#include <ros/console.h>

using namespace std;

IdDictionary::IdDictionary()
{
	translated = false;
}

bool IdDictionary::contains(int n)
{
	mutex.lock();

	for (vector<int>::iterator it = ids.begin(); it != ids.end(); it++) {
		if (*it == n) {
			mutex.unlock();
			return true;
		}
	}

	mutex.unlock();
	return false;
}

void IdDictionary::insert(int n)
{
	if (contains(n)) {
		return;
	}

	if (translated) {
		ROS_ERROR("insert: Ids already translated!");
	}

	mutex.lock();

	ROS_DEBUG("Inserted id %d", n);
	ids.push_back(n);

	mutex.unlock();
}

int IdDictionary::size()
{
	return ids.size();
}

void IdDictionary::translateIds()
{
	if (translated) {
		return;
	}

	mutex.lock();

	ROS_DEBUG("Translating dictionary with %d ids", size());

	translated = true;

	std::sort(ids.begin(), ids.end());
	int id = 0;

	for (vector<int>::iterator it = ids.begin(); it != ids.end(); it++, id++) {
		backward[id] = *it;
		forward[*it] = id;
	}

	mutex.unlock();
}

bool IdDictionary::isTranslated()
{
	return translated;
}

int IdDictionary::getForward(int n)
{
	if (!translated) {
		ROS_ERROR("getForward: Ids not translated!");
	}

	mutex.lock();

	if (forward.count(n)) {
		int result = forward[n];
		mutex.unlock();
		return result;
	} else {
		ROS_ERROR("getForward: Unknown id %d", n);
		mutex.unlock();
		return -1;
	}
}

int IdDictionary::getBackward(int n)
{
	if (!translated) {
		ROS_ERROR("getBackward: Ids not translated!");
	}

	mutex.lock();

	if (backward.count(n)) {
		int result = backward[n];
		mutex.unlock();
		return result;
	} else {
		ROS_ERROR("getBackward: Unknown id %d", n);
		mutex.unlock();
		return -1;
	}
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "gtest/gtest.h"

#include "PathPattern.h"

TEST(PathPattern, CompareEqualPaths) {
  auto a = PathPattern("/abba/cadabra");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathsWithTrailingSlash) {
  auto a = PathPattern("/abba/cadabra/");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareDifferentLength) {
  auto a = PathPattern("/abba/cadabra/gattaca");
  auto b = Path("/abba/cadabra");
  EXPECT_FALSE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithSingleWildcard) {
  auto a = PathPattern("/abba/?/gattaca");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithMultipleWildcards) {
  auto a = PathPattern("/?/cadabra/?");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcard) {
  auto a = PathPattern("/abba/*");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcardAndSamePartCount) {
  auto a = PathPattern("/abba/*");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcardCatchAll) {
  auto a = PathPattern("/*");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithMixedWildcards) {
  auto a = PathPattern("/?/cadabra/*");
  auto b = Path("/abba/cadabra/gattaca/c");
  auto c = Path("/abba/cordoba/gattaca/c");
  EXPECT_TRUE(a.match(b));
  EXPECT_FALSE(a.tch(c));
}<commit_msg>Fixed accidental deletion of characters in test code.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "gtest/gtest.h"

#include "PathPattern.h"

TEST(PathPattern, CompareEqualPaths) {
  auto a = PathPattern("/abba/cadabra");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathsWithTrailingSlash) {
  auto a = PathPattern("/abba/cadabra/");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareDifferentLength) {
  auto a = PathPattern("/abba/cadabra/gattaca");
  auto b = Path("/abba/cadabra");
  EXPECT_FALSE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithSingleWildcard) {
  auto a = PathPattern("/abba/?/gattaca");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithMultipleWildcards) {
  auto a = PathPattern("/?/cadabra/?");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcard) {
  auto a = PathPattern("/abba/*");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcardAndSamePartCount) {
  auto a = PathPattern("/abba/*");
  auto b = Path("/abba/cadabra");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithGreedyWildcardCatchAll) {
  auto a = PathPattern("/*");
  auto b = Path("/abba/cadabra/gattaca");
  EXPECT_TRUE(a.match(b));
}

TEST(PathPattern, CompareEqualPathWithMixedWildcards) {
  auto a = PathPattern("/?/cadabra/*");
  auto b = Path("/abba/cadabra/gattaca/c");
  auto c = Path("/abba/cordoba/gattaca/c");
  EXPECT_TRUE(a.match(b));
  EXPECT_FALSE(a.match(c));
}<|endoftext|>


<commit_before>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * Contact: Kimmo Surakka <kimmo.surakka@nokia.com>
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "maliitquickpluginfactory.h"
#include "maliit-plugins-quick/input-method/minputmethodquickplugin.h"

class MyPlugin
    : public MInputMethodQuickPlugin
{
    Q_DISABLE_COPY(MyPlugin)

private:
    const QString m_filename;

public:
    explicit MyPlugin(const QString &filename)
        : MInputMethodQuickPlugin()
        , m_filename(filename)
    {}

    virtual QString qmlFileName() const
    {
        return m_filename;
    }

    virtual QString name() const
    {
        static QFileInfo info(m_filename);
        return info.baseName();
    }
};

MaliitQuickPluginFactory::MaliitQuickPluginFactory(QObject *parent)
    : QObject(parent)
    , MImAbstractPluginFactory()
{}

MaliitQuickPluginFactory::~MaliitQuickPluginFactory()
{}

QString MaliitQuickPluginFactory::fileExtension() const
{
    return "qml";
}

MInputMethodPlugin * MaliitQuickPluginFactory::create(const QString &file) const
{
    return new MyPlugin(file);
}

Q_EXPORT_PLUGIN2(MaliitQuickPluginFactory, MaliitQuickPluginFactory)
<commit_msg>Normalize some includes<commit_after>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * Contact: Kimmo Surakka <kimmo.surakka@nokia.com>
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "maliitquickpluginfactory.h"
#include "minputmethodquickplugin.h"

class MyPlugin
    : public MInputMethodQuickPlugin
{
    Q_DISABLE_COPY(MyPlugin)

private:
    const QString m_filename;

public:
    explicit MyPlugin(const QString &filename)
        : MInputMethodQuickPlugin()
        , m_filename(filename)
    {}

    virtual QString qmlFileName() const
    {
        return m_filename;
    }

    virtual QString name() const
    {
        static QFileInfo info(m_filename);
        return info.baseName();
    }
};

MaliitQuickPluginFactory::MaliitQuickPluginFactory(QObject *parent)
    : QObject(parent)
    , MImAbstractPluginFactory()
{}

MaliitQuickPluginFactory::~MaliitQuickPluginFactory()
{}

QString MaliitQuickPluginFactory::fileExtension() const
{
    return "qml";
}

MInputMethodPlugin * MaliitQuickPluginFactory::create(const QString &file) const
{
    return new MyPlugin(file);
}

Q_EXPORT_PLUGIN2(MaliitQuickPluginFactory, MaliitQuickPluginFactory)
<|endoftext|>