<commit_before>/*
 * Copyright (C) 2004-2008 Marc Boris Duerner
 *
 * 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.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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
 */

#include "cxxtools/streambuffer.h"
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <cxxtools/log.h>

log_define("cxxtools.streambuffer")

namespace cxxtools {

StreamBuffer::StreamBuffer(IODevice& ioDevice, size_t bufferSize, bool extend)
: _ioDevice(&ioDevice),
  _ibufferSize(bufferSize+4),
  _ibuffer(0),
  _obufferSize(bufferSize),
  _obuffer(0),
  _oextend(extend),
  _pbmax(4),
  _reading(false),
  _flushing(false)
{
    this->setg(0, 0, 0);
    this->setp(0, 0);

    this->attach(ioDevice);
}

StreamBuffer::StreamBuffer(size_t bufferSize, bool extend)
: _ioDevice(0),
  _ibufferSize(bufferSize+4),
  _ibuffer(0),
  _obufferSize(bufferSize),
  _obuffer(0),
  _oextend(extend),
  _pbmax(4),
  _reading(false),
  _flushing(false)
{
    this->setg(0, 0, 0);
    this->setp(0, 0);
}

StreamBuffer::~StreamBuffer()
{
    delete[] _ibuffer;
    delete[] _obuffer;
}

void StreamBuffer::attach(IODevice& ioDevice)
{
    if( ioDevice.busy() )
        throw IOPending( CXXTOOLS_ERROR_MSG("IODevice in use") );

    if(_ioDevice)
    {
        if( _ioDevice->busy() )
            throw IOPending( CXXTOOLS_ERROR_MSG("IODevice in use") );

        disconnect(ioDevice.inputReady, *this, &StreamBuffer::onRead);
        disconnect(ioDevice.outputReady, *this, &StreamBuffer::onWrite);
    }

    _ioDevice = &ioDevice;
    connect(ioDevice.inputReady, *this, &StreamBuffer::onRead);
    connect(ioDevice.outputReady, *this, &StreamBuffer::onWrite);
}

IODevice* StreamBuffer::device()
{
    return _ioDevice;
}

void StreamBuffer::beginRead()
{
    if(_reading || _ioDevice == 0)
        return;

    if( ! _ibuffer )
    {
        _ibuffer = new char[_ibufferSize];
    }

    size_t putback = _pbmax;
    size_t leftover = 0;

    // keep chars for putback
    if( this->gptr() )
    {
        putback = std::min<size_t>( gptr() - eback(), _pbmax);
        char* to = _ibuffer + _pbmax - putback;
        char* from = this->gptr() - putback;

        if(to == from)
            throw std::logic_error( CXXTOOLS_ERROR_MSG("StreamBuffer is full") );

        leftover = egptr() - gptr();
        std::memmove( to, from, putback + leftover );
    }

    size_t used = _pbmax + leftover;
    _ioDevice->beginRead( _ibuffer + used, _ibufferSize - used );
    _reading = true;

    this->setg( _ibuffer + (_pbmax - putback), // start of get area
                _ibuffer + used, // gptr position
                _ibuffer + used ); // end of get area
}

void StreamBuffer::onRead(IODevice& dev)
{
    this->endRead();
    inputReady.send(*this);
}

void StreamBuffer::endRead()
{
    size_t readSize = _ioDevice->endRead();
    _reading = false;

    this->setg( this->eback(), // start of get area
                this->gptr(), // gptr position
                this->egptr() + readSize ); // end of get area
}

StreamBuffer::int_type StreamBuffer::underflow()
{
    log_trace("underflow");

    if( ! _ioDevice )
        return traits_type::eof();

    if(_reading)
        this->endRead();

    if( this->gptr() < this->egptr() )
        return traits_type::to_int_type( *(this->gptr()) );

    if( _ioDevice->eof() )
        return traits_type::eof();

    if( ! _ibuffer )
    {
        _ibuffer = new char[_ibufferSize];
    }

    size_t putback = _pbmax;

    if( this->gptr() )
    {
        putback = std::min<size_t>(this->gptr() - this->eback(), _pbmax);
        std::memmove( _ibuffer + (_pbmax - putback),
                      this->gptr() - putback,
                      putback );
    }

    size_t readSize = _ioDevice->read( _ibuffer + _pbmax, _ibufferSize - _pbmax );

    this->setg( _ibuffer + _pbmax - putback,    // start of get area
                _ibuffer + _pbmax,              // gptr position
                _ibuffer + _pbmax + readSize ); // end of get area

    if( _ioDevice->eof() )
        return traits_type::eof();

    return traits_type::to_int_type( *(this->gptr()) );
}

std::streamsize StreamBuffer::showfull()
{
    return 0;
}

void StreamBuffer::beginWrite()
{
    log_trace("beginWrite; out_avail=" << out_avail());

    if(_flushing || _ioDevice == 0 )
        return;

    if( this->pptr() )
    {
        size_t avail = this->pptr() - this->pbase();
        if(avail > 0)
        {
            _ioDevice->beginWrite(_obuffer, avail);
            _flushing = true;
        }
    }
}

void StreamBuffer::discard()
{
    if (_reading || _flushing)
        throw IOPending( CXXTOOLS_ERROR_MSG("discard failed - streambuffer is in use") );

    if (gptr())
        this->setg(_ibuffer, _ibuffer + _ibufferSize, _ibuffer + _ibufferSize);

    if (pptr())
        this->setp(_obuffer, _obuffer + _obufferSize);
}

void StreamBuffer::onWrite(IODevice& dev)
{
    log_trace("onWrite");

    this->endWrite();
    outputReady.send(*this);
}

void StreamBuffer::endWrite()
{
    log_trace("endWrite; out_avail=" << out_avail());

    _flushing = false;
    size_t leftover = 0;

    if( this->pptr() )
    {
        size_t avail = this->pptr() - this->pbase();
        size_t written = _ioDevice->endWrite();

        leftover = avail - written;
        if(leftover > 0)
        {
            traits_type::move(_obuffer, _obuffer + written, leftover);
        }
    }

    this->setp(_obuffer, _obuffer + _obufferSize);
    this->pbump( leftover );
}

StreamBuffer::int_type StreamBuffer::overflow(int_type ch)
{
    log_trace("overflow(" << ch << ')');

    if( ! _ioDevice )
        return traits_type::eof();

    if( ! _obuffer )
    {
        _obuffer = new char[_obufferSize];
        this->setp(_obuffer, _obuffer + _obufferSize);
    }
    else if(_flushing) // beginWrite is unfinished
    {
        this->endWrite();
    }
    else if (traits_type::eq_int_type( ch, traits_type::eof() ) || !_oextend)
    {
        // normal blocking overflow case
        size_t avail = this->pptr() - _obuffer;
        size_t written = _ioDevice->write(_obuffer, avail);
        size_t leftover = avail - written;

        if(leftover > 0)
        {
            traits_type::move(_obuffer, _obuffer + written, leftover);
        }
        this->setp(_obuffer, _obuffer + _obufferSize);
        this->pbump( leftover );
    }
    else
    {
        // if the buffer area is extensible and overflow is not called by
        // sync/flush we copy the output buffer to a larger one
        size_t bufsize = _obufferSize + (_obufferSize/2);
        char* buf = new char[ bufsize ];
        traits_type::move(buf, _obuffer, _obufferSize);
        std::swap(_obuffer, buf);
        _obufferSize = bufsize;
        delete [] buf;
    }

    // if the overflow char is not EOF put it in buffer
    if( traits_type::eq_int_type(ch, traits_type::eof()) ==  false )
    {
        *this->pptr() = traits_type::to_char_type(ch);
        this->pbump(1);
    }

    return traits_type::not_eof(ch);
}

StreamBuffer::int_type StreamBuffer::pbackfail(StreamBuffer::int_type)
{
    return traits_type::eof();
}

int StreamBuffer::sync()
{
    log_trace("sync");

    if( ! _ioDevice )
        return 0;

    if( pptr() )
    {
        while( this->pptr() > this->pbase() )
        {
            const int_type ch = this->overflow( traits_type::eof() );
            if( ch == traits_type::eof() )
            {
                return -1;
            }

            _ioDevice->sync();
        }
    }

    return 0;
}

std::streamsize StreamBuffer::xspeekn(char* buffer, std::streamsize size)
{
    if( traits_type::eof() == this->underflow() )
        return 0;

    const std::streamsize avail = this->egptr() - this->gptr();
    size = std::min(avail, size);
    if(size == 0) {
        return 0;
    }

    std::memcpy(buffer, this->gptr(), sizeof(char) * size);
    return size;
}

StreamBuffer::pos_type
StreamBuffer::seekoff(off_type off, std::ios::seekdir dir, std::ios::openmode)
{
    pos_type ret =  pos_type( off_type(-1) );

    if ( ! _ioDevice || ! _ioDevice->enabled() ||
         ! _ioDevice->seekable() || off == 0)
    {
        return ret;
    }

    if(_flushing)
    {
        this->endWrite();
    }

    if(_reading)
    {
        this->endRead();
    }

    ret = _ioDevice->seek(off, dir);

    // eliminate currently buffered sequence
    discard();

    return ret;
}

StreamBuffer::pos_type
StreamBuffer::seekpos(pos_type p, std::ios::openmode mode)
{
    return this->seekoff(p, std::ios::beg, mode);
}

}
<commit_msg>fix streambuffer extend<commit_after>/*
 * Copyright (C) 2004-2008 Marc Boris Duerner
 *
 * 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.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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
 */

#include "cxxtools/streambuffer.h"
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <cxxtools/log.h>

log_define("cxxtools.streambuffer")

namespace cxxtools {

StreamBuffer::StreamBuffer(IODevice& ioDevice, size_t bufferSize, bool extend)
: _ioDevice(&ioDevice),
  _ibufferSize(bufferSize+4),
  _ibuffer(0),
  _obufferSize(bufferSize),
  _obuffer(0),
  _oextend(extend),
  _pbmax(4),
  _reading(false),
  _flushing(false)
{
    this->setg(0, 0, 0);
    this->setp(0, 0);

    this->attach(ioDevice);
}

StreamBuffer::StreamBuffer(size_t bufferSize, bool extend)
: _ioDevice(0),
  _ibufferSize(bufferSize+4),
  _ibuffer(0),
  _obufferSize(bufferSize),
  _obuffer(0),
  _oextend(extend),
  _pbmax(4),
  _reading(false),
  _flushing(false)
{
    this->setg(0, 0, 0);
    this->setp(0, 0);
}

StreamBuffer::~StreamBuffer()
{
    delete[] _ibuffer;
    delete[] _obuffer;
}

void StreamBuffer::attach(IODevice& ioDevice)
{
    if( ioDevice.busy() )
        throw IOPending( CXXTOOLS_ERROR_MSG("IODevice in use") );

    if(_ioDevice)
    {
        if( _ioDevice->busy() )
            throw IOPending( CXXTOOLS_ERROR_MSG("IODevice in use") );

        disconnect(ioDevice.inputReady, *this, &StreamBuffer::onRead);
        disconnect(ioDevice.outputReady, *this, &StreamBuffer::onWrite);
    }

    _ioDevice = &ioDevice;
    connect(ioDevice.inputReady, *this, &StreamBuffer::onRead);
    connect(ioDevice.outputReady, *this, &StreamBuffer::onWrite);
}

IODevice* StreamBuffer::device()
{
    return _ioDevice;
}

void StreamBuffer::beginRead()
{
    if(_reading || _ioDevice == 0)
        return;

    if( ! _ibuffer )
    {
        _ibuffer = new char[_ibufferSize];
    }

    size_t putback = _pbmax;
    size_t leftover = 0;

    // keep chars for putback
    if( this->gptr() )
    {
        putback = std::min<size_t>( gptr() - eback(), _pbmax);
        char* to = _ibuffer + _pbmax - putback;
        char* from = this->gptr() - putback;

        if(to == from)
            throw std::logic_error( CXXTOOLS_ERROR_MSG("StreamBuffer is full") );

        leftover = egptr() - gptr();
        std::memmove( to, from, putback + leftover );
    }

    size_t used = _pbmax + leftover;
    _ioDevice->beginRead( _ibuffer + used, _ibufferSize - used );
    _reading = true;

    this->setg( _ibuffer + (_pbmax - putback), // start of get area
                _ibuffer + used, // gptr position
                _ibuffer + used ); // end of get area
}

void StreamBuffer::onRead(IODevice& dev)
{
    this->endRead();
    inputReady.send(*this);
}

void StreamBuffer::endRead()
{
    size_t readSize = _ioDevice->endRead();
    _reading = false;

    this->setg( this->eback(), // start of get area
                this->gptr(), // gptr position
                this->egptr() + readSize ); // end of get area
}

StreamBuffer::int_type StreamBuffer::underflow()
{
    log_trace("underflow");

    if( ! _ioDevice )
        return traits_type::eof();

    if(_reading)
        this->endRead();

    if( this->gptr() < this->egptr() )
        return traits_type::to_int_type( *(this->gptr()) );

    if( _ioDevice->eof() )
        return traits_type::eof();

    if( ! _ibuffer )
    {
        _ibuffer = new char[_ibufferSize];
    }

    size_t putback = _pbmax;

    if( this->gptr() )
    {
        putback = std::min<size_t>(this->gptr() - this->eback(), _pbmax);
        std::memmove( _ibuffer + (_pbmax - putback),
                      this->gptr() - putback,
                      putback );
    }

    size_t readSize = _ioDevice->read( _ibuffer + _pbmax, _ibufferSize - _pbmax );

    this->setg( _ibuffer + _pbmax - putback,    // start of get area
                _ibuffer + _pbmax,              // gptr position
                _ibuffer + _pbmax + readSize ); // end of get area

    if( _ioDevice->eof() )
        return traits_type::eof();

    return traits_type::to_int_type( *(this->gptr()) );
}

std::streamsize StreamBuffer::showfull()
{
    return 0;
}

void StreamBuffer::beginWrite()
{
    log_trace("beginWrite; out_avail=" << out_avail());

    if(_flushing || _ioDevice == 0 )
        return;

    if( this->pptr() )
    {
        size_t avail = this->pptr() - this->pbase();
        if(avail > 0)
        {
            _ioDevice->beginWrite(_obuffer, avail);
            _flushing = true;
        }
    }
}

void StreamBuffer::discard()
{
    if (_reading || _flushing)
        throw IOPending( CXXTOOLS_ERROR_MSG("discard failed - streambuffer is in use") );

    if (gptr())
        this->setg(_ibuffer, _ibuffer + _ibufferSize, _ibuffer + _ibufferSize);

    if (pptr())
        this->setp(_obuffer, _obuffer + _obufferSize);
}

void StreamBuffer::onWrite(IODevice& dev)
{
    log_trace("onWrite");

    this->endWrite();
    outputReady.send(*this);
}

void StreamBuffer::endWrite()
{
    log_trace("endWrite; out_avail=" << out_avail());

    _flushing = false;
    size_t leftover = 0;

    if( this->pptr() )
    {
        size_t avail = this->pptr() - this->pbase();
        size_t written = _ioDevice->endWrite();

        leftover = avail - written;
        if(leftover > 0)
        {
            traits_type::move(_obuffer, _obuffer + written, leftover);
        }
    }

    this->setp(_obuffer, _obuffer + _obufferSize);
    this->pbump( leftover );
}

StreamBuffer::int_type StreamBuffer::overflow(int_type ch)
{
    log_trace("overflow(" << ch << ')');

    if( ! _ioDevice )
        return traits_type::eof();

    if( ! _obuffer )
    {
        _obuffer = new char[_obufferSize];
        this->setp(_obuffer, _obuffer + _obufferSize);
    }
    else if(_flushing) // beginWrite is unfinished
    {
        this->endWrite();
    }
    else if (traits_type::eq_int_type( ch, traits_type::eof() ) || !_oextend)
    {
        // normal blocking overflow case
        size_t avail = this->pptr() - _obuffer;
        size_t written = _ioDevice->write(_obuffer, avail);
        size_t leftover = avail - written;

        if(leftover > 0)
        {
            traits_type::move(_obuffer, _obuffer + written, leftover);
        }
        this->setp(_obuffer, _obuffer + _obufferSize);
        this->pbump( leftover );
    }
    else
    {
        // if the buffer area is extensible and overflow is not called by
        // sync/flush we copy the output buffer to a larger one
        size_t bufsize = _obufferSize + (_obufferSize/2);
        char* buf = new char[ bufsize ];
        traits_type::copy(buf, _obuffer, _obufferSize);
        std::swap(_obuffer, buf);
        this->setp(_obuffer, _obuffer + bufsize);
        this->pbump( _obufferSize );
        _obufferSize = bufsize;
        delete [] buf;
    }

    // if the overflow char is not EOF put it in buffer
    if( traits_type::eq_int_type(ch, traits_type::eof()) ==  false )
    {
        *this->pptr() = traits_type::to_char_type(ch);
        this->pbump(1);
    }

    return traits_type::not_eof(ch);
}

StreamBuffer::int_type StreamBuffer::pbackfail(StreamBuffer::int_type)
{
    return traits_type::eof();
}

int StreamBuffer::sync()
{
    log_trace("sync");

    if( ! _ioDevice )
        return 0;

    if( pptr() )
    {
        while( this->pptr() > this->pbase() )
        {
            const int_type ch = this->overflow( traits_type::eof() );
            if( ch == traits_type::eof() )
            {
                return -1;
            }

            _ioDevice->sync();
        }
    }

    return 0;
}

std::streamsize StreamBuffer::xspeekn(char* buffer, std::streamsize size)
{
    if( traits_type::eof() == this->underflow() )
        return 0;

    const std::streamsize avail = this->egptr() - this->gptr();
    size = std::min(avail, size);
    if(size == 0) {
        return 0;
    }

    std::memcpy(buffer, this->gptr(), sizeof(char) * size);
    return size;
}

StreamBuffer::pos_type
StreamBuffer::seekoff(off_type off, std::ios::seekdir dir, std::ios::openmode)
{
    pos_type ret =  pos_type( off_type(-1) );

    if ( ! _ioDevice || ! _ioDevice->enabled() ||
         ! _ioDevice->seekable() || off == 0)
    {
        return ret;
    }

    if(_flushing)
    {
        this->endWrite();
    }

    if(_reading)
    {
        this->endRead();
    }

    ret = _ioDevice->seek(off, dir);

    // eliminate currently buffered sequence
    discard();

    return ret;
}

StreamBuffer::pos_type
StreamBuffer::seekpos(pos_type p, std::ios::openmode mode)
{
    return this->seekoff(p, std::ios::beg, mode);
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 The Bitcoin Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcserver.h"
#include "rpcclient.h"

#include "base58.h"
#include "wallet.h"

#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>

using namespace std;
using namespace json_spirit;

extern Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL);
extern Value CallRPC(string args);

extern CWallet* pwalletMain;

BOOST_AUTO_TEST_SUITE(rpc_wallet_tests)

BOOST_AUTO_TEST_CASE(rpc_addmultisig)
{
    LOCK(pwalletMain->cs_wallet);

    rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;

    // old, 65-byte-long:
    const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
    // new, compressed:
    const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";

    Value v;
    CBitcoinAddress address;
    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error);

    BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error);

    string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error);

    string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error);
}

BOOST_AUTO_TEST_CASE(rpc_wallet)
{
    // Test RPC calls for various wallet statistics
    Value r;

    LOCK2(cs_main, pwalletMain->cs_wallet);

    CPubKey demoPubkey = pwalletMain->GenerateNewKey();
	CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
	Value retValue;
	string strAccount = "walletDemoAccount";
	string strPurpose = "receive";
	BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
		CWalletDB walletdb(pwalletMain->strWalletFile);
		CAccount account;
		account.vchPubKey = demoPubkey;
		pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
		walletdb.WriteAccount(strAccount, account);
	});

    CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
        CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));

	/*********************************
	 * 			setaccount
	 *********************************/
	BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"));
	/* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */
	BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error);
	BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
	/* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
	BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);

    /*********************************
     * 			listunspent
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
    BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error);
    BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []"));
    BOOST_CHECK(r.get_array().empty());

    /*********************************
	 * 		listreceivedbyaddress
	 *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress"));
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error);

    /*********************************
	 * 		listreceivedbyaccount
	 *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount"));
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);

    /*********************************
	 * 		getrawchangeaddress
	 *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress"));

    /*********************************
	 * 		getnewaddress
	 *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getnewaddress"));
    BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount"));

    /*********************************
	 * 		getaccountaddress
	 *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\""));
	BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account
	BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount));
	BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get());

	/*********************************
	 * 			getaccount
	 *********************************/
	BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error);
	BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString()));

	/*********************************
	 * 	signmessage + verifymessage
	 *********************************/
	BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage"));
	BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error);
	/* Should throw error because this address is not loaded in the wallet */
	BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error);

	/* missing arguments */
	BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString()), runtime_error);
	BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str()), runtime_error);
	/* Illegal address */
	BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error);
	/* wrong address */
	BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false);
	/* Correct address and signature but wrong message */
	BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false);
	/* Correct address, message and signature*/
	BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true);

	/*********************************
	 * 		getaddressesbyaccount
	 *********************************/
	BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error);
	BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount));
	Array arr = retValue.get_array();
	BOOST_CHECK(arr.size() > 0);
	BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());

}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Changed mixed indentation to four spaces<commit_after>// Copyright (c) 2013-2014 The Bitcoin Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcclient.h"
#include "rpcserver.h"

#include "base58.h"
#include "wallet.h"

#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>

using namespace std;
using namespace json_spirit;

extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL);
extern Value CallRPC(string args);

extern CWallet* pwalletMain;

BOOST_AUTO_TEST_SUITE(rpc_wallet_tests)

BOOST_AUTO_TEST_CASE(rpc_addmultisig)
{
    LOCK(pwalletMain->cs_wallet);

    rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;

    // old, 65-byte-long:
    const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
    // new, compressed:
    const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";

    Value v;
    CBitcoinAddress address;
    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error);

    BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error);

    string short1(address1Hex, address1Hex + sizeof(address1Hex) - 2); // last byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error);

    string short2(address1Hex + 1, address1Hex + sizeof(address1Hex)); // first byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error);
}

BOOST_AUTO_TEST_CASE(rpc_wallet)
{
    // Test RPC calls for various wallet statistics
    Value r;

    LOCK2(cs_main, pwalletMain->cs_wallet);

    CPubKey demoPubkey = pwalletMain->GenerateNewKey();
    CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
    Value retValue;
    string strAccount = "walletDemoAccount";
    string strPurpose = "receive";
    BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
                           CWalletDB walletdb(pwalletMain->strWalletFile);
                           CAccount account;
                           account.vchPubKey = demoPubkey;
                           pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
                           walletdb.WriteAccount(strAccount, account);
    });

    CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
    CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));

    /*********************************
     * 			setaccount
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"));
    /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */
    BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
    /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
    BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);

    /*********************************
     * 			listunspent
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
    BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error);
    BOOST_CHECK_NO_THROW(r = CallRPC("listunspent 0 1 []"));
    BOOST_CHECK(r.get_array().empty());

    /*********************************
     * 		listreceivedbyaddress
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress"));
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error);

    /*********************************
     * 		listreceivedbyaccount
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount"));
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
    BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);

    /*********************************
     * 		getrawchangeaddress
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress"));

    /*********************************
     * 		getnewaddress
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getnewaddress"));
    BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount"));

    /*********************************
     * 		getaccountaddress
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\""));
    BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account
    BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount));
    BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get());

    /*********************************
     * 			getaccount
     *********************************/
    BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString()));

    /*********************************
     * 	signmessage + verifymessage
     *********************************/
    BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage"));
    BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error);
    /* Should throw error because this address is not loaded in the wallet */
    BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error);

    /* missing arguments */
    BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error);
    BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str()), runtime_error);
    /* Illegal address */
    BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error);
    /* wrong address */
    BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false);
    /* Correct address and signature but wrong message */
    BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false);
    /* Correct address, message and signature*/
    BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true);

    /*********************************
     * 		getaddressesbyaccount
     *********************************/
    BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error);
    BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount));
    Array arr = retValue.get_array();
    BOOST_CHECK(arr.size() > 0);
    BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "CppUnitTest.h"
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    template<class Traits>
    class tokens
    {
        vector<typename Traits::type> tokens_;
    public:
        bool empty() const { return tokens_.size() == 0; }
        void from_string(string s)
        {
            tokens_.push_back(Traits::tokenize(s));
        }
    };
}

namespace algo { namespace spec
{
    struct test_token_traits
    {
        struct s {};
        typedef s type;
        static s tokenize(const string&) { return s(); }
    };

    typedef tokens<test_token_traits> test_tokens;

    TEST_CLASS(can_recognize_tokens)
	{
	public:

        TEST_METHOD(should_not_have_any_tokens_when_default_constructed)
		{
            test_tokens testTokens;
            Assert::IsTrue(testTokens.empty());
		}

        TEST_METHOD(should_recognize_a_token)
        {
            test_tokens testTokens;
            testTokens.from_string("s");
            Assert::IsFalse(testTokens.empty());
        }

	};
}}
<commit_msg>test rename<commit_after>#include "CppUnitTest.h"
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    template<class Traits>
    class tokens
    {
        vector<typename Traits::type> tokens_;
    public:
        bool empty() const { return tokens_.size() == 0; }
        void from_string(string s)
        {
            tokens_.push_back(Traits::tokenize(s));
        }
    };
}

namespace algo { namespace spec
{
    struct test_token_traits
    {
        struct s {};
        typedef s type;
        static s tokenize(const string&) { return s(); }
    };

    typedef tokens<test_token_traits> test_tokens;

    TEST_CLASS(can_recognize_tokens)
	{
	public:

        TEST_METHOD(should_not_have_any_tokens_when_default_constructed)
		{
            test_tokens testTokens;
            Assert::IsTrue(testTokens.empty());
		}

        TEST_METHOD(should_recognize_a_token_in_a_string)
        {
            test_tokens testTokens;
            testTokens.from_string("s");
            Assert::IsFalse(testTokens.empty());
        }

	};
}}
<|endoftext|>


<commit_before>/*
 * Server.cpp
 *
 *  Created on: 2009-09-13
 *      Author: chudy
 */

#include "network/Server.h"

#include "common.h"
#include "network/events.h"

Server::Server(int p_port) :
	m_raceServer(this)
{
	m_slots.connect(m_gameServer.sig_client_connected(), this, &Server::slotClientConnected);
	m_slots.connect(m_gameServer.sig_client_disconnected(), this, &Server::slotClientDisconnected);
	m_slots.connect(m_gameServer.sig_event_received(), this, &Server::slotEventArrived);

	m_gameServer.start(CL_StringHelp::int_to_local8(p_port));

	// TESTING
	m_raceServer.initialize();
}

Server::~Server()
{
	m_gameServer.stop();
}

void Server::update(int p_timeElapsed)
{
//	m_gameServer.process_events();
}

void Server::slotClientConnected(CL_NetGameConnection *p_netGameConnection)
{
	cl_log_event("network", "Player %1 is connected", (unsigned) p_netGameConnection);

	Player *player = new Player();
	m_connections[p_netGameConnection] = player;

	// emit the signal
	m_signalPlayerConnected.invoke(p_netGameConnection, player);
}

void Server::slotClientDisconnected(CL_NetGameConnection *p_netGameConnection)
{
	cl_log_event("network", "Player %1 disconnects", m_connections[p_netGameConnection]->getName().empty() ? CL_StringHelp::uint_to_local8((unsigned) p_netGameConnection) : m_connections[p_netGameConnection]->getName());

	std::map<CL_NetGameConnection*, Player*>::iterator itor = m_connections.find(p_netGameConnection);

	if (itor != m_connections.end()) {

		Player* player = itor->second;

		// emit the signal
		m_signalPlayerDisconnected.invoke(p_netGameConnection, player);

		// cleanup
		delete player;
		m_connections.erase(itor);
	}
}

void Server::slotEventArrived(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{

	cl_log_event("event", "Event %1 arrived", p_event.to_string());

	const CL_String eventName = p_event.get_name();

	const std::vector<CL_TempString> parts = CL_StringHelp::split_text(eventName, ":");

	if (parts[0] == EVENT_PREFIX_GENERAL) {
		if (eventName == EVENT_HI) {
			handleHiEvent(p_connection, p_event);
			return;
		}
	} else if (parts[0] == EVENT_PREFIX_RACE) {
		m_raceServer.handleEvent(p_connection, p_event);
		return;
	}

	cl_log_event("event", "Event %1 remains unhandled", p_event.to_string());

}

void Server::handleHiEvent(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{
	const CL_String playerName = p_event.get_argument(0);

	if (playerName.empty()) {
		cl_log_event("error", "Protocol error while handling %1 event", p_event.to_string());
		return;
	}

	// check availability
	bool nameAvailable = true;
	for (
		std::map<CL_NetGameConnection*, Player*>::const_iterator itor = m_connections.begin();
		itor != m_connections.end();
		++itor
	) {
		if (itor->second->getName() == playerName) {
			nameAvailable = false;
		}
	}

	if (!nameAvailable) {
		// refuse of nick set
		reply(p_connection, CL_NetGameEvent(EVENT_PLAYER_NICK_IN_USE));

		cl_log_event("event", "Name '%1' already in use for player '%2'", playerName, (unsigned) p_connection);
	} else {
		// resend player's connection event
		m_connections[p_connection]->setName(playerName);
		send(CL_NetGameEvent(EVENT_PLAYER_CONNECTED, playerName), p_connection);

		cl_log_event("event", "Player %1 is now known as '%2'", (unsigned) p_connection, playerName);

		// and send him the list of other players
		std::pair<CL_NetGameConnection*, Player*> pair;
		foreach(pair, m_connections) {
			if (pair.first == p_connection) {
				continue;
			}

			reply(p_connection, CL_NetGameEvent(EVENT_PLAYER_CONNECTED, pair.second->getName()));
		}
	}
}

void Server::reply(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{
	p_connection->send_event(p_event);
}

void Server::send(const CL_NetGameEvent &p_event, const CL_NetGameConnection* p_ignore)
{
	std::pair<CL_NetGameConnection*, Player*> pair;
	foreach(pair, m_connections) {
		if (pair.first != p_ignore) {
			pair.first->send_event(p_event);
		}
	}
}

void Server::prepareRace()
{

}
<commit_msg>* Little readability correction[C<commit_after>/*
 * Server.cpp
 *
 *  Created on: 2009-09-13
 *      Author: chudy
 */

#include "network/Server.h"

#include "common.h"
#include "network/events.h"

Server::Server(int p_port) :
	m_raceServer(this)
{
	m_slots.connect(m_gameServer.sig_client_connected(), this, &Server::slotClientConnected);
	m_slots.connect(m_gameServer.sig_client_disconnected(), this, &Server::slotClientDisconnected);
	m_slots.connect(m_gameServer.sig_event_received(), this, &Server::slotEventArrived);

	m_gameServer.start(CL_StringHelp::int_to_local8(p_port));

	// TESTING
	m_raceServer.initialize();
}

Server::~Server()
{
	m_gameServer.stop();
}

void Server::update(int p_timeElapsed)
{
//	m_gameServer.process_events();
}

void Server::slotClientConnected(CL_NetGameConnection *p_netGameConnection)
{
	cl_log_event("network", "Player %1 is connected", (unsigned) p_netGameConnection);

	Player *player = new Player();
	m_connections[p_netGameConnection] = player;

	// emit the signal
	m_signalPlayerConnected.invoke(p_netGameConnection, player);
}

void Server::slotClientDisconnected(CL_NetGameConnection *p_netGameConnection)
{
	cl_log_event("network", "Player %1 disconnects", m_connections[p_netGameConnection]->getName().empty() ? CL_StringHelp::uint_to_local8((unsigned) p_netGameConnection) : m_connections[p_netGameConnection]->getName());

	std::map<CL_NetGameConnection*, Player*>::iterator itor = m_connections.find(p_netGameConnection);

	if (itor != m_connections.end()) {

		Player* player = itor->second;

		// emit the signal
		m_signalPlayerDisconnected.invoke(p_netGameConnection, player);

		// cleanup
		delete player;
		m_connections.erase(itor);
	}
}

void Server::slotEventArrived(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{
	cl_log_event("event", "Event %1 arrived", p_event.to_string());

	const CL_String eventName = p_event.get_name();
	const std::vector<CL_TempString> parts = CL_StringHelp::split_text(eventName, ":");

	if (parts[0] == EVENT_PREFIX_GENERAL) {
		if (eventName == EVENT_HI) {
			handleHiEvent(p_connection, p_event);
			return;
		}
	} else if (parts[0] == EVENT_PREFIX_RACE) {
		m_raceServer.handleEvent(p_connection, p_event);
		return;
	}

	cl_log_event("event", "Event %1 remains unhandled", p_event.to_string());

}

void Server::handleHiEvent(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{
	const CL_String playerName = p_event.get_argument(0);

	if (playerName.empty()) {
		cl_log_event("error", "Protocol error while handling %1 event", p_event.to_string());
		return;
	}

	// check availability
	bool nameAvailable = true;
	std::pair<CL_NetGameConnection*, Player*> pair;
	foreach (pair, m_connections) {
		if (pair.second->getName() == playerName) {
			nameAvailable = false;
		}
	}

	if (!nameAvailable) {
		// refuse of nick set
		reply(p_connection, CL_NetGameEvent(EVENT_PLAYER_NICK_IN_USE));

		cl_log_event("event", "Name '%1' already in use for player '%2'", playerName, (unsigned) p_connection);
	} else {
		// resend player's connection event

		m_connections[p_connection]->setName(playerName);

		send(CL_NetGameEvent(EVENT_PLAYER_CONNECTED, playerName), p_connection);

		cl_log_event("event", "Player %1 is now known as '%2'", (unsigned) p_connection, playerName);

		// and send him the list of other players
		std::pair<CL_NetGameConnection*, Player*> pair;
		foreach(pair, m_connections) {
			if (pair.first == p_connection) {
				continue;
			}

			CL_NetGameEvent replyEvent(EVENT_PLAYER_CONNECTED, pair.second->getName());

			reply(p_connection, replyEvent);
		}
	}
}

void Server::reply(CL_NetGameConnection *p_connection, const CL_NetGameEvent &p_event)
{
	p_connection->send_event(p_event);
}

void Server::send(const CL_NetGameEvent &p_event, const CL_NetGameConnection* p_ignore)
{
	std::pair<CL_NetGameConnection*, Player*> pair;
	foreach(pair, m_connections) {
		if (pair.first != p_ignore) {
			pair.first->send_event(p_event);
		}
	}
}

void Server::prepareRace()
{

}
<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1998 Graydon Hoare <graydon@pobox.com>
 * Copyright (C) 2000 Stefan Seefeld <stefan@berlin-consortium.org>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */
#ifndef _ServerImpl_hh
#define _ServerImpl_hh

#include <Warsaw/config.hh>
#include <Warsaw/Server.hh>
#include <Warsaw/Graphic.hh>
#include <Berlin/KitImpl.hh>
#include <Prague/Sys/Thread.hh>
#include <Prague/Sys/Plugin.hh>
#include <vector>
#include <string>
#include <map>

class ServerContextImpl;

//. the Server just hands out new ServerContexts to
//. people who are connecting.  it might want to do some checking on
//. the incoming ClientContext's credentials, but at the moment it doesn't.
class ServerImpl : public virtual POA_Warsaw::Server,
                   public virtual PortableServer::RefCountServantBase
{
  friend class ServerContextImpl;

  typedef std::vector<ServerContextImpl *> clist_t;
  typedef std::vector<Prague::Plugin<KitImpl> *> pmap_t;
  typedef std::vector<KitImpl *> kmap_t;
  typedef std::map<std::string, CORBA::Object_var> smap_t;
  typedef std::multimap<std::string, Warsaw::Kit::PropertySeq_var> PluginList;

public:
  //. Create() can be called once only! It creates the one server-object.
  static ServerImpl *create(const CORBA::PolicyList &);
  //. Get a reference to the server in use.
  static ServerImpl *instance();

  //. Create a ServerContext. This is what is called by a client that
  //. wants to connect to this server. A ServerContext holds all objects
  //. generated by a client and gets deleted (destructing all those objects)
  //. as soon as the client terminated (or the server is no longer
  //. able to ping the client).
  virtual Warsaw::ServerContext_ptr
  create_server_context(Warsaw::ClientContext_ptr c)
    throw (Warsaw::SecurityException);

  //. Set_singleton() 'publishes' a given Object under a given name.
  //. Clients then can request access to this object with get_singleton.
  //. The server makes sure that there are no two objects by the same name,
  //. throwing an SingletonFailureException as soon as someone tries to
  //. give a name allready known to the server,
  virtual void set_singleton(const char *, CORBA::Object_ptr)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);
  //. This method removes the object of the given name from the
  //. list of known singletons. It does not destruct the object
  virtual void remove_singleton(const char *)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);
  virtual CORBA::Object_ptr get_singleton(const char *)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);

  //. Finds the requested Kit and returns a reference to it.
  template <class K>
  typename K::_ptr_type resolve(const char *,
	  const Warsaw::Kit::PropertySeq &,
	  PortableServer::POA_ptr);

  //. Starts the server.
  void start();
  //. Stops the server.
  void stop();
  //. Pings all ServerContexts and destroys those that do not
  //. respond (aka. crashed).

  void ping();
  //. This scans all directories given as modulepath in berlinrc for Kits
  //. and loads the whole lot of them.

  void scan(const std::string &);
  //. Deletes all known Kits.
  void clear();
  //. Returns a list of all known Pluginnames (kits) and their properties.
  PluginList list();

protected:
  //. Finds the requested kit and loads it. This is a helper function only.
  //. Use resolve,
  KitImpl *create(const char *,
		  const Warsaw::Kit::PropertySeq &,
		  PortableServer::POA_ptr);

private:
  ServerImpl(const CORBA::PolicyList &);

  //. Called every second to ping the clients.
  static void *run(void *);

  //. Destroys a given Servercontext (and with that the client's resources
  //. in this server).
  static void destroy_context(ServerContextImpl *);
  CORBA::PolicyList  _policies;
  Prague::Thread     _thread;
  Prague::Mutex      _mutex;
  smap_t             _singletons;
  clist_t            _contexts;
  pmap_t             _plugins;
    kmap_t             _kits;
  static ServerImpl *_server;
};

template <class K>
typename K::_ptr_type ServerImpl::resolve(const char *type, const Warsaw::Kit::PropertySeq &properties, PortableServer::POA_ptr poa)
{
    KitImpl *kit = create(type, properties, poa);
    if (!kit) return K::_nil();
    typename K::_var_type reference;
    try
      {
	reference = K::_narrow(Warsaw::Kit_var(kit->_this()));
      }
    catch (CORBA::Exception &e)
      {
	std::cerr << "Cannot narrow reference: " << e << std::endl;
	return K::_nil();
      }
    if (CORBA::is_nil(reference))
      {
	std::cerr << "Reference has incorrect type" << std::endl;
	return K::_nil();
      }
    _kits.push_back(kit);
    return reference._retn();
}

#endif
<commit_msg>I accidentally moved a typedef into private. Dunno why that happened. Sorry for any inconvinience that might have caused.<commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1998 Graydon Hoare <graydon@pobox.com>
 * Copyright (C) 2000 Stefan Seefeld <stefan@berlin-consortium.org>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */
#ifndef _ServerImpl_hh
#define _ServerImpl_hh

#include <Warsaw/config.hh>
#include <Warsaw/Server.hh>
#include <Warsaw/Graphic.hh>
#include <Berlin/KitImpl.hh>
#include <Prague/Sys/Thread.hh>
#include <Prague/Sys/Plugin.hh>
#include <vector>
#include <string>
#include <map>

class ServerContextImpl;

//. the Server just hands out new ServerContexts to
//. people who are connecting.  it might want to do some checking on
//. the incoming ClientContext's credentials, but at the moment it doesn't.
class ServerImpl : public virtual POA_Warsaw::Server,
                   public virtual PortableServer::RefCountServantBase
{
  friend class ServerContextImpl;

  typedef std::vector<ServerContextImpl *> clist_t;
  typedef std::vector<Prague::Plugin<KitImpl> *> pmap_t;
  typedef std::vector<KitImpl *> kmap_t;
  typedef std::map<std::string, CORBA::Object_var> smap_t;

public:
  typedef std::multimap<std::string, Warsaw::Kit::PropertySeq_var> PluginList;

  //. Create() can be called once only! It creates the one server-object.
  static ServerImpl *create(const CORBA::PolicyList &);
  //. Get a reference to the server in use.
  static ServerImpl *instance();

  //. Create a ServerContext. This is what is called by a client that
  //. wants to connect to this server. A ServerContext holds all objects
  //. generated by a client and gets deleted (destructing all those objects)
  //. as soon as the client terminated (or the server is no longer
  //. able to ping the client).
  virtual Warsaw::ServerContext_ptr
  create_server_context(Warsaw::ClientContext_ptr c)
    throw (Warsaw::SecurityException);

  //. Set_singleton() 'publishes' a given Object under a given name.
  //. Clients then can request access to this object with get_singleton.
  //. The server makes sure that there are no two objects by the same name,
  //. throwing an SingletonFailureException as soon as someone tries to
  //. give a name allready known to the server,
  virtual void set_singleton(const char *, CORBA::Object_ptr)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);
  //. This method removes the object of the given name from the
  //. list of known singletons. It does not destruct the object
  virtual void remove_singleton(const char *)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);
  virtual CORBA::Object_ptr get_singleton(const char *)
    throw (Warsaw::SecurityException, Warsaw::SingletonFailureException);

  //. Finds the requested Kit and returns a reference to it.
  template <class K>
  typename K::_ptr_type resolve(const char *,
	  const Warsaw::Kit::PropertySeq &,
	  PortableServer::POA_ptr);

  //. Starts the server.
  void start();
  //. Stops the server.
  void stop();
  //. Pings all ServerContexts and destroys those that do not
  //. respond (aka. crashed).

  void ping();
  //. This scans all directories given as modulepath in berlinrc for Kits
  //. and loads the whole lot of them.

  void scan(const std::string &);
  //. Deletes all known Kits.
  void clear();
  //. Returns a list of all known Pluginnames (kits) and their properties.
  PluginList list();

protected:
  //. Finds the requested kit and loads it. This is a helper function only.
  //. Use resolve,
  KitImpl *create(const char *,
		  const Warsaw::Kit::PropertySeq &,
		  PortableServer::POA_ptr);

private:
  ServerImpl(const CORBA::PolicyList &);

  //. Called every second to ping the clients.
  static void *run(void *);

  //. Destroys a given Servercontext (and with that the client's resources
  //. in this server).
  static void destroy_context(ServerContextImpl *);
  CORBA::PolicyList  _policies;
  Prague::Thread     _thread;
  Prague::Mutex      _mutex;
  smap_t             _singletons;
  clist_t            _contexts;
  pmap_t             _plugins;
    kmap_t             _kits;
  static ServerImpl *_server;
};

template <class K>
typename K::_ptr_type ServerImpl::resolve(const char *type, const Warsaw::Kit::PropertySeq &properties, PortableServer::POA_ptr poa)
{
    KitImpl *kit = create(type, properties, poa);
    if (!kit) return K::_nil();
    typename K::_var_type reference;
    try
      {
	reference = K::_narrow(Warsaw::Kit_var(kit->_this()));
      }
    catch (CORBA::Exception &e)
      {
	std::cerr << "Cannot narrow reference: " << e << std::endl;
	return K::_nil();
      }
    if (CORBA::is_nil(reference))
      {
	std::cerr << "Reference has incorrect type" << std::endl;
	return K::_nil();
      }
    _kits.push_back(kit);
    return reference._retn();
}

#endif
<|endoftext|>


<commit_before>#include "shared.hh"
#include "local-store.hh"
#include "util.hh"
#include "serialise.hh"
#include "worker-protocol.hh"
#include "archive.hh"

#include <iostream>

using namespace nix;

Path readStorePath(Source & from)
{
    Path path = readString(from);
    assertStorePath(path);
    return path;
}

PathSet readStorePaths(Source & from)
{
    PathSet paths = readStringSet(from);
    for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
        assertStorePath(*i);
    return paths;
}

void processConnection(Source & from, Sink & to)
{
    store = boost::shared_ptr<StoreAPI>(new LocalStore(true));

    unsigned int magic = readInt(from);
    if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch");

    writeInt(WORKER_MAGIC_2, to);

    debug("greeting exchanged");

    bool quit = false;

    unsigned int opCount = 0;

    do {

        WorkerOp op = (WorkerOp) readInt(from);

        opCount++;

        switch (op) {

        case wopQuit: {
            /* Close the database. */
            store.reset((StoreAPI *) 0);
            writeInt(1, to);
            quit = true;
            break;
        }

        case wopIsValidPath: {
            Path path = readStorePath(from);
            writeInt(store->isValidPath(path), to);
            break;
        }

        case wopHasSubstitutes: {
            Path path = readStorePath(from);
            writeInt(store->hasSubstitutes(path), to);
            break;
        }

        case wopQueryPathHash: {
            Path path = readStorePath(from);
            writeString(printHash(store->queryPathHash(path)), to);
            break;
        }

        case wopQueryReferences:
        case wopQueryReferrers: {
            Path path = readStorePath(from);
            PathSet paths;
            if (op == wopQueryReferences)
                store->queryReferences(path, paths);
            else
                store->queryReferrers(path, paths);
            writeStringSet(paths, to);
            break;
        }

        case wopAddToStore: {
            /* !!! uberquick hack */
            string baseName = readString(from);
            bool fixed = readInt(from) == 1;
            bool recursive = readInt(from) == 1;
            string hashAlgo = readString(from);

            Path tmp = createTempDir();
            Path tmp2 = tmp + "/" + baseName;
            restorePath(tmp2, from);

            writeString(store->addToStore(tmp2, fixed, recursive, hashAlgo), to);

            deletePath(tmp);
            break;
        }

        case wopAddTextToStore: {
            string suffix = readString(from);
            string s = readString(from);
            PathSet refs = readStorePaths(from);
            writeString(store->addTextToStore(suffix, s, refs), to);
            break;
        }

        case wopBuildDerivations: {
            PathSet drvs = readStorePaths(from);
            store->buildDerivations(drvs);
            writeInt(1, to);
            break;
        }

        case wopEnsurePath: {
            Path path = readStorePath(from);
            store->ensurePath(path);
            writeInt(1, to);
            break;
        }

        case wopAddTempRoot: {
            Path path = readStorePath(from);
            store->addTempRoot(path);
            writeInt(1, to);
            break;
        }

        case wopSyncWithGC: {
            store->syncWithGC();
            writeInt(1, to);
            break;
        }

        default:
            throw Error(format("invalid operation %1%") % op);
        }

    } while (!quit);

    printMsg(lvlError, format("%1% worker operations") % opCount);
}

void run(Strings args)
{
    bool slave = false;
    bool daemon = false;

    for (Strings::iterator i = args.begin(); i != args.end(); ) {
        string arg = *i++;
        if (arg == "--slave") slave = true;
        if (arg == "--daemon") daemon = true;
    }

    if (slave) {
        FdSource source(STDIN_FILENO);
        FdSink sink(STDOUT_FILENO);
        processConnection(source, sink);
    }

    else if (daemon)
        throw Error("daemon mode not implemented");

    else
        throw Error("must be run in either --slave or --daemon mode");
}

#include "help.txt.hh"

void printHelp()
{
    std::cout << string((char *) helpText, sizeof helpText);
}

string programId = "nix-worker";
<commit_msg>* Run the worker in a separate session to prevent terminal signals   from interfering.<commit_after>#include "shared.hh"
#include "local-store.hh"
#include "util.hh"
#include "serialise.hh"
#include "worker-protocol.hh"
#include "archive.hh"

#include <iostream>

using namespace nix;

Path readStorePath(Source & from)
{
    Path path = readString(from);
    assertStorePath(path);
    return path;
}

PathSet readStorePaths(Source & from)
{
    PathSet paths = readStringSet(from);
    for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
        assertStorePath(*i);
    return paths;
}

void processConnection(Source & from, Sink & to)
{
    store = boost::shared_ptr<StoreAPI>(new LocalStore(true));

    unsigned int magic = readInt(from);
    if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch");

    writeInt(WORKER_MAGIC_2, to);

    debug("greeting exchanged");

    bool quit = false;

    unsigned int opCount = 0;

    do {

        WorkerOp op = (WorkerOp) readInt(from);

        opCount++;

        switch (op) {

        case wopQuit: {
            /* Close the database. */
            store.reset((StoreAPI *) 0);
            writeInt(1, to);
            quit = true;
            break;
        }

        case wopIsValidPath: {
            Path path = readStorePath(from);
            writeInt(store->isValidPath(path), to);
            break;
        }

        case wopHasSubstitutes: {
            Path path = readStorePath(from);
            writeInt(store->hasSubstitutes(path), to);
            break;
        }

        case wopQueryPathHash: {
            Path path = readStorePath(from);
            writeString(printHash(store->queryPathHash(path)), to);
            break;
        }

        case wopQueryReferences:
        case wopQueryReferrers: {
            Path path = readStorePath(from);
            PathSet paths;
            if (op == wopQueryReferences)
                store->queryReferences(path, paths);
            else
                store->queryReferrers(path, paths);
            writeStringSet(paths, to);
            break;
        }

        case wopAddToStore: {
            /* !!! uberquick hack */
            string baseName = readString(from);
            bool fixed = readInt(from) == 1;
            bool recursive = readInt(from) == 1;
            string hashAlgo = readString(from);

            Path tmp = createTempDir();
            Path tmp2 = tmp + "/" + baseName;
            restorePath(tmp2, from);

            writeString(store->addToStore(tmp2, fixed, recursive, hashAlgo), to);

            deletePath(tmp);
            break;
        }

        case wopAddTextToStore: {
            string suffix = readString(from);
            string s = readString(from);
            PathSet refs = readStorePaths(from);
            writeString(store->addTextToStore(suffix, s, refs), to);
            break;
        }

        case wopBuildDerivations: {
            PathSet drvs = readStorePaths(from);
            store->buildDerivations(drvs);
            writeInt(1, to);
            break;
        }

        case wopEnsurePath: {
            Path path = readStorePath(from);
            store->ensurePath(path);
            writeInt(1, to);
            break;
        }

        case wopAddTempRoot: {
            Path path = readStorePath(from);
            store->addTempRoot(path);
            writeInt(1, to);
            break;
        }

        case wopSyncWithGC: {
            store->syncWithGC();
            writeInt(1, to);
            break;
        }

        default:
            throw Error(format("invalid operation %1%") % op);
        }

    } while (!quit);

    printMsg(lvlError, format("%1% worker operations") % opCount);
}

void run(Strings args)
{
    bool slave = false;
    bool daemon = false;

    for (Strings::iterator i = args.begin(); i != args.end(); ) {
        string arg = *i++;
        if (arg == "--slave") slave = true;
        if (arg == "--daemon") daemon = true;
    }

    if (slave) {
        FdSource source(STDIN_FILENO);
        FdSink sink(STDOUT_FILENO);

        /* This prevents us from receiving signals from the terminal
           when we're running in setuid mode. */
        if (setsid() == -1)
            throw SysError(format("creating a new session"));

        processConnection(source, sink);
    }

    else if (daemon)
        throw Error("daemon mode not implemented");

    else
        throw Error("must be run in either --slave or --daemon mode");
}

#include "help.txt.hh"

void printHelp()
{
    std::cout << string((char *) helpText, sizeof helpText);
}

string programId = "nix-worker";
<|endoftext|>


<commit_before>/**********************************************************************
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
********************************************************************/

#include "cl_uberv2_generator.h"

using namespace Baikal;

CLUberV2Generator::CLUberV2Generator()
{

}

CLUberV2Generator::~CLUberV2Generator()
{
}

void CLUberV2Generator::AddMaterial(UberV2Material::Ptr material)
{
    uint32_t layers = material->GetLayers();
    // Check if we already have such material type processed
    if (m_materials.find(layers) != m_materials.end())
    {
        return;
    }

    UberV2Sources src;
    MaterialGeneratePrepareInputs(material, &src);
    MaterialGenerateGetPdf(material, &src);
    MaterialGenerateSample(material, &src);
    MaterialGenerateGetBxDFType(material, &src);
    MaterialGenerateEvaluate(material, &src);
    m_materials[layers] = src;
}

void CLUberV2Generator::MaterialGeneratePrepareInputs(UberV2Material::Ptr material, UberV2Sources *sources)
{
    static const std::string reader_function_arguments("material_attributes[offset++], dg, input_map_values, TEXTURE_ARGS");
    struct LayerReader
    {
        std::string variable;
        std::string reader;
    };
    // Should have same order as in ClwSceneController::WriteMaterial
    static const std::vector<std::pair<UberV2Material::Layers, std::vector<LayerReader>>> readers =
    {
        {
            UberV2Material::Layers::kEmissionLayer,
            {
                {"shader_data.emission_color", "GetInputMapFloat4"}
            }
        },
        {
            UberV2Material::Layers::kCoatingLayer,
            {
                {"shader_data.coating_color", "GetInputMapFloat4"},
                {"shader_data.coating_ior", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kReflectionLayer,
            {
                {"shader_data.coating_color", "GetInputMapFloat4"},
                {"shader_data.coating_ior", "GetInputMapFloat"},
                {"shader_data.reflection_color", "GetInputMapFloat4"},
                {"shader_data.reflection_roughness", "GetInputMapFloat"},
                {"shader_data.reflection_anisotropy", "GetInputMapFloat"},
                {"shader_data.reflection_anisotropy_rotation", "GetInputMapFloat"},
                {"shader_data.reflection_ior", "GetInputMapFloat"},
                {"shader_data.reflection_metalness", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kDiffuseLayer,
            {
                {"shader_data.diffuse_color", "GetInputMapFloat4"}
            }
        },
        {
            UberV2Material::Layers::kRefractionLayer,
            {
                {"shader_data.refraction_color", "GetInputMapFloat4"},
                {"shader_data.refraction_roughness", "GetInputMapFloat"},
                {"shader_data.refraction_ior", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kTransparencyLayer,
            {
                {"shader_data.transparency", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kShadingNormalLayer,
            {
                {"shader_data.shading_normal", "GetInputMapFloat4"},
            }
        },
        {
            UberV2Material::Layers::kSSSLayer,
            {
                {"shader_data.sss_absorption_color", "GetInputMapFloat4"},
                {"shader_data.sss_scatter_color", "GetInputMapFloat4"},
                {"shader_data.sss_subsurface_color", "GetInputMapFloat4"},
                {"shader_data.sss_absorption_distance", "GetInputMapFloat"},
                {"shader_data.sss_scatter_distance", "GetInputMapFloat"},
                {"shader_data.sss_scatter_direction", "GetInputMapFloat"},
            }
        }
    };

    // Reserve 4k. This should be enought for maximum configuration
    sources->m_prepare_inputs.reserve(4096);
    // Write base code
    uint32_t layers = material->GetLayers();
    sources->m_prepare_inputs =
        "UberV2ShaderData UberV2PrepareInputs" + std::to_string(layers) + "("
        "DifferentialGeometry const* dg, GLOBAL InputMapData const* restrict input_map_values,"
        "GLOBAL int const* restrict material_attributes, TEXTURE_ARG_LIST)\n"
        "{\n"
        "\tUberV2ShaderData shader_data;\n"
        "\tint offset = dg->mat.offset + 1;\n";

    // Write code for each layer
    for (auto &reader: readers)
    {
        // If current layer exist in material - write it
        if ((layers & reader.first) == reader.first)
        {
            for (auto &r : reader.second)
            {
                sources->m_prepare_inputs += std::string("\t") + r.variable + " = " + r.reader + "(" + reader_function_arguments + ");\n";
            }
        }
    }

    sources->m_prepare_inputs += "\treturn shader_data;\n}";
}

void CLUberV2Generator::MaterialGenerateGetPdf(UberV2Material::Ptr material, UberV2Sources *sources)
{

}

void CLUberV2Generator::MaterialGenerateSample(UberV2Material::Ptr material, UberV2Sources *sources)
{
    uint32_t layers = material->GetLayers();
    sources->m_sample =
        "float3 UberV2_Sample(DifferentialGeometry const* dg, float3 wi, TEXTURE_ARG_LIST, float2 sample, float3* wo, float* pdf,
        "UberV2ShaderData const* shader_data)\n"
        "{\n"
        "\tconst int sampledComponent = Bxdf_UberV2_GetSampledComponent(dg);\n";

    soruces->m_sample +=
        "\treturn 0.f;\n"
        "}\n";

}
void CLUberV2Generator::MaterialGenerateGetBxDFType(UberV2Material::Ptr material, UberV2Sources *sources)
{

    uint32_t layers = material->GetLayers();
    sources->m_get_bxdf_type = "void GetMaterialBxDFType" + std::to_string(layers) + "("
        "float3 wi, Sampler* sampler, SAMPLER_ARG_LIST, DifferentialGeometry* dg, UberV2ShaderData const* shader_data)\n"
        "{\n";
        "\tint bxdf_flags = 0;\n";

    // If we have layer that requires fresnel blend (reflection/refraction/coating)
    if ((layers &
        (UberV2Material::Layers::kReflectionLayer | UberV2Material::Layers::kRefractionLayer | UberV2Material::Layers::kCoatingLayer ))
        != 0)
    {

        sources->m_get_bxdf_type += "\tconst float ndotwi = dot(dg->n, wi);\n";
    }

    if ((layers & UberV2Material::Layers::kEmissionLayer) == UberV2Material::Layers::kEmissionLayer)
    {
        sources->m_get_bxdf_type += "\tbxdf_flags |= kBxdfFlagsEmissive;\n";
    }

    if ((layers & UberV2Material::Layers::kTransparencyLayer) == UberV2Material::Layers::kTransparencyLayer)
    {
        // If layer have transparency check in OpenCL if we sample it and if we sample it - return
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tif (sample < shader_data->transparency)\n"
            "\t{\n"
            "\t\tbxdf_flags |= (kBxdfFlagsTransparency | kBxdfFlagsSingular);\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleTransparency);\n"
            "\t\treturn;\n"
            "\t}\n";
    }

    // Check refraction layer. If we have it and plan to sample it - set flags and sampled component
    if ((layers & UberV2Material::Layers::kRefractionLayer) == UberV2Material::Layers::kRefractionLayer)
    {
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tconst float fresnel = CalculateFresnel(1.0f, shader_data->refraction_ior, ndotwi);\n"
            "\tif (sample >= fresnel)\n"
            "\t{\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleRefraction);\n"
            "\t\tif (shader_data->refraction_roughness < ROUGHNESS_EPS)\n"
            "\t\t{\n"
            "\t\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\t}\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);"
            "\t\treturn;\n"
            "\t}\n";
    }

    sources->m_get_bxdf_type +=
        "\tbxdf_flags |= kBxdfFlagsBrdf;\n"
        "\tfloat top_ior = 1.0f;\n";

    if ((layers & UberV2Material::Layers::kCoatingLayer) == UberV2Material::Layers::kCoatingLayer)
    {
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tconst float fresnel = CalculateFresnel(top_ior, shader_data->coating_ior, ndotwi);\n"
            "\tif (sample < fresnel)\n"
            "\t{\n"
            "\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleCoating);\n"
            "\t\treturn;\n"
            "\t}\n"
            "\ttop_ior = shader_data->coating_ior;\n";
    }

    if ((layers & UberV2Material::Layers::kReflectionLayer) == UberV2Material::Layers::kReflectionLayer)
    {
        sources->m_get_bxdf_type +=
            "\tconst float fresnel = CalculateFresnel(top_ior, shader_data->reflection_ior, ndotwi);\n"
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tif (sample < fresnel)\n"
            "\t{\n"
            "\t\tif (shader_data->reflection_roughness < ROUGHNESS_EPS)\n"
            "\t\t{\n"
            "\t\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\t}\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleReflection);\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\treturn;\n"
            "\t}\n";

    }

    sources->m_get_bxdf_type +=
        "\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleDiffuse);\n"
        "\tBxdf_SetFlags(dg, bxdf_flags);\n"
        "return;\n"
        "}\n";
}

void CLUberV2Generator::MaterialGenerateEvaluate(UberV2Material::Ptr material, UberV2Sources *sources)
{

}
<commit_msg>Minor fixes for MaterialGenerateSample<commit_after>/**********************************************************************
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
********************************************************************/

#include "cl_uberv2_generator.h"

using namespace Baikal;

CLUberV2Generator::CLUberV2Generator()
{

}

CLUberV2Generator::~CLUberV2Generator()
{
}

void CLUberV2Generator::AddMaterial(UberV2Material::Ptr material)
{
    uint32_t layers = material->GetLayers();
    // Check if we already have such material type processed
    if (m_materials.find(layers) != m_materials.end())
    {
        return;
    }

    UberV2Sources src;
    MaterialGeneratePrepareInputs(material, &src);
    MaterialGenerateGetPdf(material, &src);
    MaterialGenerateSample(material, &src);
    MaterialGenerateGetBxDFType(material, &src);
    MaterialGenerateEvaluate(material, &src);
    m_materials[layers] = src;
}

void CLUberV2Generator::MaterialGeneratePrepareInputs(UberV2Material::Ptr material, UberV2Sources *sources)
{
    static const std::string reader_function_arguments("material_attributes[offset++], dg, input_map_values, TEXTURE_ARGS");
    struct LayerReader
    {
        std::string variable;
        std::string reader;
    };
    // Should have same order as in ClwSceneController::WriteMaterial
    static const std::vector<std::pair<UberV2Material::Layers, std::vector<LayerReader>>> readers =
    {
        {
            UberV2Material::Layers::kEmissionLayer,
            {
                {"shader_data.emission_color", "GetInputMapFloat4"}
            }
        },
        {
            UberV2Material::Layers::kCoatingLayer,
            {
                {"shader_data.coating_color", "GetInputMapFloat4"},
                {"shader_data.coating_ior", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kReflectionLayer,
            {
                {"shader_data.coating_color", "GetInputMapFloat4"},
                {"shader_data.coating_ior", "GetInputMapFloat"},
                {"shader_data.reflection_color", "GetInputMapFloat4"},
                {"shader_data.reflection_roughness", "GetInputMapFloat"},
                {"shader_data.reflection_anisotropy", "GetInputMapFloat"},
                {"shader_data.reflection_anisotropy_rotation", "GetInputMapFloat"},
                {"shader_data.reflection_ior", "GetInputMapFloat"},
                {"shader_data.reflection_metalness", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kDiffuseLayer,
            {
                {"shader_data.diffuse_color", "GetInputMapFloat4"}
            }
        },
        {
            UberV2Material::Layers::kRefractionLayer,
            {
                {"shader_data.refraction_color", "GetInputMapFloat4"},
                {"shader_data.refraction_roughness", "GetInputMapFloat"},
                {"shader_data.refraction_ior", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kTransparencyLayer,
            {
                {"shader_data.transparency", "GetInputMapFloat"}
            }
        },
        {
            UberV2Material::Layers::kShadingNormalLayer,
            {
                {"shader_data.shading_normal", "GetInputMapFloat4"},
            }
        },
        {
            UberV2Material::Layers::kSSSLayer,
            {
                {"shader_data.sss_absorption_color", "GetInputMapFloat4"},
                {"shader_data.sss_scatter_color", "GetInputMapFloat4"},
                {"shader_data.sss_subsurface_color", "GetInputMapFloat4"},
                {"shader_data.sss_absorption_distance", "GetInputMapFloat"},
                {"shader_data.sss_scatter_distance", "GetInputMapFloat"},
                {"shader_data.sss_scatter_direction", "GetInputMapFloat"},
            }
        }
    };

    // Reserve 4k. This should be enought for maximum configuration
    sources->m_prepare_inputs.reserve(4096);
    // Write base code
    uint32_t layers = material->GetLayers();
    sources->m_prepare_inputs =
        "UberV2ShaderData UberV2PrepareInputs" + std::to_string(layers) + "("
        "DifferentialGeometry const* dg, GLOBAL InputMapData const* restrict input_map_values,"
        "GLOBAL int const* restrict material_attributes, TEXTURE_ARG_LIST)\n"
        "{\n"
        "\tUberV2ShaderData shader_data;\n"
        "\tint offset = dg->mat.offset + 1;\n";

    // Write code for each layer
    for (auto &reader: readers)
    {
        // If current layer exist in material - write it
        if ((layers & reader.first) == reader.first)
        {
            for (auto &r : reader.second)
            {
                sources->m_prepare_inputs += std::string("\t") + r.variable + " = " + r.reader + "(" + reader_function_arguments + ");\n";
            }
        }
    }

    sources->m_prepare_inputs += "\treturn shader_data;\n}";
}

void CLUberV2Generator::MaterialGenerateGetPdf(UberV2Material::Ptr material, UberV2Sources *sources)
{

}

void CLUberV2Generator::MaterialGenerateSample(UberV2Material::Ptr material, UberV2Sources *sources)
{
    uint32_t layers = material->GetLayers();
    sources->m_sample =
        "float3 UberV2_Sample" + std::to_string(layers) + "(DifferentialGeometry const* dg, float3 wi, TEXTURE_ARG_LIST, float2 sample, float3* wo, float* pdf,"
        "UberV2ShaderData const* shader_data)\n"
        "{\n"
        "\tconst int sampledComponent = Bxdf_UberV2_GetSampledComponent(dg);\n";

    sources->m_sample +=
        "\treturn 0.f;\n"
        "}\n";

}
void CLUberV2Generator::MaterialGenerateGetBxDFType(UberV2Material::Ptr material, UberV2Sources *sources)
{

    uint32_t layers = material->GetLayers();
    sources->m_get_bxdf_type = "void GetMaterialBxDFType" + std::to_string(layers) + "("
        "float3 wi, Sampler* sampler, SAMPLER_ARG_LIST, DifferentialGeometry* dg, UberV2ShaderData const* shader_data)\n"
        "{\n";
        "\tint bxdf_flags = 0;\n";

    // If we have layer that requires fresnel blend (reflection/refraction/coating)
    if ((layers &
        (UberV2Material::Layers::kReflectionLayer | UberV2Material::Layers::kRefractionLayer | UberV2Material::Layers::kCoatingLayer ))
        != 0)
    {

        sources->m_get_bxdf_type += "\tconst float ndotwi = dot(dg->n, wi);\n";
    }

    if ((layers & UberV2Material::Layers::kEmissionLayer) == UberV2Material::Layers::kEmissionLayer)
    {
        sources->m_get_bxdf_type += "\tbxdf_flags |= kBxdfFlagsEmissive;\n";
    }

    if ((layers & UberV2Material::Layers::kTransparencyLayer) == UberV2Material::Layers::kTransparencyLayer)
    {
        // If layer have transparency check in OpenCL if we sample it and if we sample it - return
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tif (sample < shader_data->transparency)\n"
            "\t{\n"
            "\t\tbxdf_flags |= (kBxdfFlagsTransparency | kBxdfFlagsSingular);\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleTransparency);\n"
            "\t\treturn;\n"
            "\t}\n";
    }

    // Check refraction layer. If we have it and plan to sample it - set flags and sampled component
    if ((layers & UberV2Material::Layers::kRefractionLayer) == UberV2Material::Layers::kRefractionLayer)
    {
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tconst float fresnel = CalculateFresnel(1.0f, shader_data->refraction_ior, ndotwi);\n"
            "\tif (sample >= fresnel)\n"
            "\t{\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleRefraction);\n"
            "\t\tif (shader_data->refraction_roughness < ROUGHNESS_EPS)\n"
            "\t\t{\n"
            "\t\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\t}\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);"
            "\t\treturn;\n"
            "\t}\n";
    }

    sources->m_get_bxdf_type +=
        "\tbxdf_flags |= kBxdfFlagsBrdf;\n"
        "\tfloat top_ior = 1.0f;\n";

    if ((layers & UberV2Material::Layers::kCoatingLayer) == UberV2Material::Layers::kCoatingLayer)
    {
        sources->m_get_bxdf_type +=
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tconst float fresnel = CalculateFresnel(top_ior, shader_data->coating_ior, ndotwi);\n"
            "\tif (sample < fresnel)\n"
            "\t{\n"
            "\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleCoating);\n"
            "\t\treturn;\n"
            "\t}\n"
            "\ttop_ior = shader_data->coating_ior;\n";
    }

    if ((layers & UberV2Material::Layers::kReflectionLayer) == UberV2Material::Layers::kReflectionLayer)
    {
        sources->m_get_bxdf_type +=
            "\tconst float fresnel = CalculateFresnel(top_ior, shader_data->reflection_ior, ndotwi);\n"
            "\tfloat sample = Sampler_Sample1D(sampler, SAMPLER_ARGS);\n"
            "\tif (sample < fresnel)\n"
            "\t{\n"
            "\t\tif (shader_data->reflection_roughness < ROUGHNESS_EPS)\n"
            "\t\t{\n"
            "\t\t\tbxdf_flags |= kBxdfFlagsSingular;\n"
            "\t\t}\n"
            "\t\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleReflection);\n"
            "\t\tBxdf_SetFlags(dg, bxdf_flags);\n"
            "\t\treturn;\n"
            "\t}\n";

    }

    sources->m_get_bxdf_type +=
        "\tBxdf_UberV2_SetSampledComponent(dg, kBxdfUberV2SampleDiffuse);\n"
        "\tBxdf_SetFlags(dg, bxdf_flags);\n"
        "return;\n"
        "}\n";
}

void CLUberV2Generator::MaterialGenerateEvaluate(UberV2Material::Ptr material, UberV2Sources *sources)
{

}
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2014 iCub Facility, Istituto Italiano di Tecnologia
 * Author: Lorenzo Natale
 * email: lorenzo.natale@iit.it
 * Permission is granted to copy, distribute, and/or modify this program
 * under the terms of the GNU General Public License, version 2 or any
 * later version published by the Free Software Foundation.
 *
 * A copy of the license can be found at
 * http://www.robotcub.org/icub/license/gpl.txt
 *
 * 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
*/

#include "TestCamera.h"

#include <yarp/os/BufferedPort.h>
#include <yarp/sig/Image.h>
#include <yarp/os/Network.h>

using namespace yarp::os;
using namespace yarp::sig;

// these values can be parameters if needed but better to keep it simple
const int TIME=3;
const int FREQUENCY=30;
const int FRAMES_TOLERANCE=10;

using namespace Logger;

TestCamera::TestCamera(yarp::os::Property& configuration) : UnitTest(configuration)
{

}

TestCamera::~TestCamera()
{

}

bool TestCamera::init(yarp::os::Property &configuration)
{
    if (!configuration.check("portname"))
        return false;

    portname=configuration.find("portname").asString();

    return true;
}

bool TestCamera::run()
{
    BufferedPort<Image> port;
    if (!port.open("/iCubTest/camera"))
    {
        checkTrue(false, "opening port, is YARP network working?");
        return true;
    }

    Logger::report("connecting from %s to %s\n", port.getName().c_str(), portname.c_str());
    if (!Network::connect(portname, port.getName()))
    {
        checkTrue(false, "could not connect to remote port, camera unavailable");
        return true;
    }

    printf("Reading images...");

    double timeStart=yarp::os::Time::now();
    double timeNow=timeStart;

    int frames=0;
    while(timeNow<timeStart+TIME)
        {
           Image *image=port.read(false);

           if (image!=0)
               frames++;

           yarp::os::Time::delay(0.01);
           timeNow=yarp::os::Time::now();
           printf(".");
        }

    printf("\n");
    int expectedFrames=TIME*FREQUENCY;
    Logger::report("Received %d frames, expecting %d\n", frames, expectedFrames);

    checkTrue((abs(frames-expectedFrames)<FRAMES_TOLERANCE), "checking number of received frames");

    return true;
}
<commit_msg>speed up camera test<commit_after>// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2014 iCub Facility, Istituto Italiano di Tecnologia
 * Author: Lorenzo Natale
 * email: lorenzo.natale@iit.it
 * Permission is granted to copy, distribute, and/or modify this program
 * under the terms of the GNU General Public License, version 2 or any
 * later version published by the Free Software Foundation.
 *
 * A copy of the license can be found at
 * http://www.robotcub.org/icub/license/gpl.txt
 *
 * 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
*/

#include "TestCamera.h"

#include <yarp/os/BufferedPort.h>
#include <yarp/sig/Image.h>
#include <yarp/os/Network.h>

using namespace yarp::os;
using namespace yarp::sig;

// these values can be parameters if needed but better to keep it simple
const int TIME=1;
const int FREQUENCY=30;
const int FRAMES_TOLERANCE=5;

using namespace Logger;

TestCamera::TestCamera(yarp::os::Property& configuration) : UnitTest(configuration)
{

}

TestCamera::~TestCamera()
{

}

bool TestCamera::init(yarp::os::Property &configuration)
{
    if (!configuration.check("portname"))
        return false;

    portname=configuration.find("portname").asString();

    return true;
}

bool TestCamera::run()
{
    BufferedPort<Image> port;
    if (!port.open("/iCubTest/camera"))
    {
        checkTrue(false, "opening port, is YARP network working?");
        return true;
    }

    Logger::report("connecting from %s to %s\n", port.getName().c_str(), portname.c_str());
    if (!Network::connect(portname, port.getName()))
    {
        checkTrue(false, "could not connect to remote port, camera unavailable");
        return true;
    }

    printf("Reading images...");

    double timeStart=yarp::os::Time::now();
    double timeNow=timeStart;

    int frames=0;
    while(timeNow<timeStart+TIME)
        {
           Image *image=port.read(false);

           if (image!=0)
               frames++;

           yarp::os::Time::delay(0.01);
           timeNow=yarp::os::Time::now();
           printf(".");
        }

    printf("\n");
    int expectedFrames=TIME*FREQUENCY;
    Logger::report("Received %d frames, expecting %d\n", frames, expectedFrames);

    checkTrue((abs(frames-expectedFrames)<FRAMES_TOLERANCE), "checking number of received frames");

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 midnightBITS
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "pch.h"
#include <handlers.hpp>
#include <utils.hpp>
#include "api_handler.hpp"

namespace FastCGI { namespace app { namespace api
{
	APIOperationPtr Operations::_handler(Request& request)
	{
		param_t op = request.getVariable("op");
		if (!op)
			request.on400("Operation is missing");

		auto _it = m_handlers.find(op);
		if (_it == m_handlers.end()) return nullptr;
#if DEBUG_CGI
		return _it->second.ptr;
#else
		return _it->second;
#endif
	}
}}}

namespace FastCGI { namespace app { namespace reader {

	class ApiPageHandler: public Handler
	{
	public:
		std::string name() const { return "reedr API"; }

		void visit(Request& request)
		{
			api::APIOperationPtr ptr = api::Operations::handler(request);
			if (!ptr)
				request.on400("Operation not recognized");

			SessionPtr session = request.getSession();
			PageTranslation tr;
			if (!tr.init(session, request))
				request.on500();

			ptr->render(session, request, tr);
		}
	};

}}}

REGISTER_HANDLER("/data/api", FastCGI::app::reader::ApiPageHandler);
<commit_msg>Whole API will be JSON-based<commit_after>/*
 * Copyright (C) 2013 midnightBITS
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "pch.h"
#include <handlers.hpp>
#include <utils.hpp>
#include "api_handler.hpp"
#include "json.hpp"

namespace FastCGI { namespace app { namespace api
{
	APIOperationPtr Operations::_handler(Request& request)
	{
		param_t op = request.getVariable("op");
		if (!op)
		{
			request.setHeader("Content-Type", "application/json; charset=utf-8");
			request.setHeader("Status", "400 Operation is missing");
			request << "{\"error\":\"Operation is missing\"}";
			request.die();
		}

		auto _it = m_handlers.find(op);
		if (_it == m_handlers.end()) return nullptr;
#if DEBUG_CGI
		return _it->second.ptr;
#else
		return _it->second;
#endif
	}
}}}

namespace FastCGI { namespace app { namespace reader {

	class ApiPageHandler: public Handler
	{
	public:
		std::string name() const { return "reedr API"; }

		void visit(Request& request)
		{
			api::APIOperationPtr ptr = api::Operations::handler(request);
			if (!ptr)
			{
				request.setHeader("Content-Type", "application/json; charset=utf-8");
				request.setHeader("Status", "404 Operation not recognized");
				request << "{\"error\":\"Operation not recognized\",\"op\":" << json::escape(request.getVariable("op")) << "}";
				request.die();
			}

			SessionPtr session = request.getSession();
			PageTranslation tr;
			if (!tr.init(session, request))
				request.on500();

			ptr->render(session, request, tr);
		}
	};

}}}

REGISTER_HANDLER("/data/api", FastCGI::app::reader::ApiPageHandler);
<|endoftext|>