<commit_before>/*
 *  gucefCORE: GUCEF module providing O/S abstraction and generic solutions
 *  Copyright (C) 2002 - 2007.  Dinand Vanvelzen
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#include <assert.h>

#ifndef GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H
#include "CNotificationIDRegistry.h"
#define GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H
#endif /* GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H ? */

#ifndef GUCEF_CORE_GUCEF_ESSENTIALS_H
#include "gucef_essentials.h"
#define GUCEF_CORE_GUCEF_ESSENTIALS_H
#endif /* GUCEF_CORE_GUCEF_ESSENTIALS_H ? */

#include "CEvent.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

namespace GUCEF {
namespace CORE {

/*-------------------------------------------------------------------------//
//                                                                         //
//      UTILITIES                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

CEvent::CEvent( void )
    : m_eventID( 0 ) ,
      m_eventName()
{GUCEF_TRACE;
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const char* eventName )
    : m_eventID( 0 )           ,
      m_eventName( eventName )
{GUCEF_TRACE;

    // Wait for delayed initialization
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const CORE::CString& eventName )
    : m_eventID( 0 )           ,
      m_eventName( eventName )
{GUCEF_TRACE;

    // Wait for delayed initialization
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const UInt32 eventID     ,
                const CString& eventName )
    : m_eventID( eventID )     ,
      m_eventName( eventName )
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const CEvent& src )
    : m_eventID( src.m_eventID )     ,
      m_eventName( src.m_eventName )
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent::~CEvent()
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const CEvent& src )
{GUCEF_TRACE;

    if ( &src != this )
    {
        m_eventName = src.m_eventName;
        m_eventID = src.m_eventID;
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const CORE::CString& eventName )
{GUCEF_TRACE;

    if ( eventName != m_eventName )
    {
        m_eventName = eventName;
        m_eventID = 0;    // <- Wait for delayed initialization
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const char* eventName )
{GUCEF_TRACE;

    if ( eventName != m_eventName )
    {
        m_eventName = eventName;
        m_eventID = 0;    // <- Wait for delayed initialization
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator==( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID == other.m_eventID;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator!=( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID != other.m_eventID;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator<( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID < other.m_eventID;
}

/*-------------------------------------------------------------------------*/

UInt32
CEvent::GetID( void ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    return m_eventID;
}

/*-------------------------------------------------------------------------*/

CORE::CString
CEvent::GetName( void ) const
{GUCEF_TRACE;

    return m_eventName;
}

/*-------------------------------------------------------------------------*/

void
CEvent::Initialize( void ) const
{GUCEF_TRACE;
    /*
     *  In this rare occasion a const_cast is legit since we are preforming
     *  an action that has conceptually already occurred,.. initialization.
     *
     *  The fact that we cannot initialize objects right from the start
     *  while allowing event objects to be defined globally is an implementation level problem.
     */
    const_cast< CEvent& >( *this ) = CORE::CCoreGlobal::Instance()->GetNotificationIDRegistry().Lookup( m_eventName, true );
}

/*-------------------------------------------------------------------------*/

bool
CEvent::IsInitialized( void ) const
{GUCEF_TRACE;

    return m_eventID > 0;
}

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

}; /* namespace CORE */
}; /* namespace GUCEF */

/*-------------------------------------------------------------------------*/
<commit_msg>Event: Don't perform redundant lookups. A lot of events are globally defined and as such benefit from a small check to ensure we can reduce redundant lookups of event IDs on object creation<commit_after>/*
 *  gucefCORE: GUCEF module providing O/S abstraction and generic solutions
 *  Copyright (C) 2002 - 2007.  Dinand Vanvelzen
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#include <assert.h>

#ifndef GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H
#include "CNotificationIDRegistry.h"
#define GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H
#endif /* GUCEF_CORE_CNOTIFICATIONIDREGISTRY_H ? */

#ifndef GUCEF_CORE_GUCEF_ESSENTIALS_H
#include "gucef_essentials.h"
#define GUCEF_CORE_GUCEF_ESSENTIALS_H
#endif /* GUCEF_CORE_GUCEF_ESSENTIALS_H ? */

#include "CEvent.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

namespace GUCEF {
namespace CORE {

/*-------------------------------------------------------------------------//
//                                                                         //
//      UTILITIES                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

CEvent::CEvent( void )
    : m_eventID( 0 ) ,
      m_eventName()
{GUCEF_TRACE;
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const char* eventName )
    : m_eventID( 0 )           ,
      m_eventName( eventName )
{GUCEF_TRACE;

    // Wait for delayed initialization
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const CORE::CString& eventName )
    : m_eventID( 0 )           ,
      m_eventName( eventName )
{GUCEF_TRACE;

    // Wait for delayed initialization
}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const UInt32 eventID     ,
                const CString& eventName )
    : m_eventID( eventID )     ,
      m_eventName( eventName )
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent::CEvent( const CEvent& src )
    : m_eventID( src.m_eventID )     ,
      m_eventName( src.m_eventName )
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent::~CEvent()
{GUCEF_TRACE;

}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const CEvent& src )
{GUCEF_TRACE;

    if ( &src != this )
    {
        m_eventName = src.m_eventName;
        m_eventID = src.m_eventID;
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const CORE::CString& eventName )
{GUCEF_TRACE;

    if ( eventName != m_eventName )
    {
        m_eventName = eventName;
        m_eventID = 0;    // <- Wait for delayed initialization
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

CEvent&
CEvent::operator=( const char* eventName )
{GUCEF_TRACE;

    if ( eventName != m_eventName )
    {
        m_eventName = eventName;
        m_eventID = 0;    // <- Wait for delayed initialization
    }
    return *this;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator==( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID == other.m_eventID;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator!=( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID != other.m_eventID;
}

/*-------------------------------------------------------------------------*/

bool
CEvent::operator<( const CEvent& other ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    assert( other.m_eventID > 0 );
    return m_eventID < other.m_eventID;
}

/*-------------------------------------------------------------------------*/

UInt32
CEvent::GetID( void ) const
{GUCEF_TRACE;

    // If you hit the asserts below then the event object was not initialized
    assert( m_eventID > 0 );
    return m_eventID;
}

/*-------------------------------------------------------------------------*/

CORE::CString
CEvent::GetName( void ) const
{GUCEF_TRACE;

    return m_eventName;
}

/*-------------------------------------------------------------------------*/

void
CEvent::Initialize( void ) const
{GUCEF_TRACE;

    // For performance reasons we don't perform the lookup again on a non-zero id
    // Since this is for performance only we don't need to worry about thread safety on
    // the branch as a race condition merely results in an extra lookup
    if ( 0 == m_eventID )
    {
        /*
         *  In this rare occasion a const_cast is legit since we are preforming
         *  an action that has conceptually already occurred,.. initialization.
         *
         *  The fact that we cannot initialize objects right from the start
         *  while allowing event objects to be defined globally is an implementation level problem.
         */
        const_cast< CEvent& >( *this ) = CORE::CCoreGlobal::Instance()->GetNotificationIDRegistry().Lookup( m_eventName, true );
    }
}

/*-------------------------------------------------------------------------*/

bool
CEvent::IsInitialized( void ) const
{GUCEF_TRACE;

    return m_eventID > 0;
}

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

}; /* namespace CORE */
}; /* namespace GUCEF */

/*-------------------------------------------------------------------------*/
<|endoftext|>


<commit_before>//
// Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "ReduceLayer.hpp"
#include "LayerCloneBase.hpp"

#include <armnn/TypesUtils.hpp>

#include <backendsCommon/WorkloadData.hpp>
#include <backendsCommon/WorkloadFactory.hpp>

namespace armnn
{

ReduceLayer::ReduceLayer(const ReduceDescriptor& param, const char* name)
    : LayerWithParameters(1, 1, LayerType::Reduce, param, name)
{
}

std::unique_ptr<IWorkload> ReduceLayer::CreateWorkload(const IWorkloadFactory& factory) const
{
    ReduceQueueDescriptor descriptor;
    return factory.CreateReduce(descriptor, PrepInfoAndDesc(descriptor));
}

ReduceLayer* ReduceLayer::Clone(Graph& graph) const
{
    return CloneBase<ReduceLayer>(graph, m_Param, GetName());
}

void ReduceLayer::ValidateTensorShapesFromInputs()
{
    VerifyLayerConnections(1, CHECK_LOCATION());

    const TensorShape& outputShape = GetOutputSlot(0).GetTensorInfo().GetShape();

    VerifyShapeInferenceType(outputShape, m_ShapeInferenceMethod);

    const TensorInfo& input = GetInputSlot(0).GetConnection()->GetTensorInfo();

    ARMNN_ASSERT_MSG(input.GetNumDimensions() > 0 && input.GetNumDimensions() <= 4,
                     "ReduceLayer: Reduce supports up to 4D input.");

    unsigned int rank = input.GetNumDimensions();
    unsigned int outputRank = 0;

    // Calculate output dimension
    if (m_Param.m_KeepDims)
    {
        outputRank = rank;
    }
    else if (m_Param.m_vAxis.empty())
    {
        outputRank = 1;
    }
    else if (m_Param.m_vAxis.size() > input.GetNumDimensions())
    {
        throw LayerValidationException("ReduceLayer: Dimensions to reduce can not be bigger than input dimensions");
    }
    else
    {
        outputRank = input.GetNumDimensions() - armnn::numeric_cast<unsigned int>(m_Param.m_vAxis.size());
        if (outputRank == 0)
        {
            outputRank = 1;
        }
    }

    std::vector<unsigned int> dimSizes(outputRank, 1);
    if (!m_Param.m_vAxis.empty())
    {
        // Skip the dimension that has been reduced unless keepDims is true.
        unsigned int outputIndex = 0;
        for (unsigned int i = 0; i < input.GetNumDimensions(); ++i)
        {
            if (std::find(m_Param.m_vAxis.begin(), m_Param.m_vAxis.end(), i) == m_Param.m_vAxis.end())
            {
                dimSizes[outputIndex] = armnn::numeric_cast<unsigned int>(input.GetShape()[i]);
                ++outputIndex;
            }
            else if (m_Param.m_KeepDims)
            {
                dimSizes[outputIndex] = 1;
                ++outputIndex;
            }
        }
    }
    const TensorShape& inferredShape = TensorShape(outputRank, dimSizes.data());

    ValidateAndCopyShape(outputShape, inferredShape, m_ShapeInferenceMethod, "ReduceLayer");
}

void ReduceLayer::Accept(ILayerVisitor& visitor) const
{
    visitor.VisitReduceLayer(this, GetParameters(), GetName());
}

} // namespace armnn
<commit_msg>IVGCVSW-5767 'Regression on SqueezeNet v1.1'<commit_after>//
// Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "ReduceLayer.hpp"
#include "LayerCloneBase.hpp"

#include <armnn/TypesUtils.hpp>

#include <backendsCommon/WorkloadData.hpp>
#include <backendsCommon/WorkloadFactory.hpp>

namespace armnn
{

ReduceLayer::ReduceLayer(const ReduceDescriptor& param, const char* name)
    : LayerWithParameters(1, 1, LayerType::Reduce, param, name)
{
}

std::unique_ptr<IWorkload> ReduceLayer::CreateWorkload(const IWorkloadFactory& factory) const
{
    ReduceQueueDescriptor descriptor;
    descriptor.m_Parameters.m_vAxis           = m_Param.m_vAxis;
    descriptor.m_Parameters.m_KeepDims        = m_Param.m_KeepDims;
    descriptor.m_Parameters.m_ReduceOperation = m_Param.m_ReduceOperation;
    SetAdditionalInfo(descriptor);

    return factory.CreateReduce(descriptor, PrepInfoAndDesc(descriptor));
}

ReduceLayer* ReduceLayer::Clone(Graph& graph) const
{
    auto layer =  CloneBase<ReduceLayer>(graph, m_Param, GetName());
    layer->m_Param.m_vAxis           = m_Param.m_vAxis;
    layer->m_Param.m_KeepDims        = m_Param.m_KeepDims;
    layer->m_Param.m_ReduceOperation = m_Param.m_ReduceOperation;

    return std::move(layer);
}

void ReduceLayer::ValidateTensorShapesFromInputs()
{
    VerifyLayerConnections(1, CHECK_LOCATION());

    const TensorShape& outputShape = GetOutputSlot(0).GetTensorInfo().GetShape();

    VerifyShapeInferenceType(outputShape, m_ShapeInferenceMethod);

    const TensorInfo& input = GetInputSlot(0).GetConnection()->GetTensorInfo();

    ARMNN_ASSERT_MSG(input.GetNumDimensions() > 0 && input.GetNumDimensions() <= 4,
                     "ReduceLayer: Reduce supports up to 4D input.");

    unsigned int rank = input.GetNumDimensions();
    unsigned int outputRank = 0;

    // Calculate output dimension
    if (m_Param.m_KeepDims)
    {
        outputRank = rank;
    }
    else if (m_Param.m_vAxis.empty())
    {
        outputRank = 1;
    }
    else if (m_Param.m_vAxis.size() > input.GetNumDimensions())
    {
        throw LayerValidationException("ReduceLayer: Dimensions to reduce can not be bigger than input dimensions");
    }
    else
    {
        outputRank = input.GetNumDimensions() - armnn::numeric_cast<unsigned int>(m_Param.m_vAxis.size());
        if (outputRank == 0)
        {
            outputRank = 1;
        }
    }

    std::vector<unsigned int> dimSizes(outputRank, 1);
    if (!m_Param.m_vAxis.empty())
    {
        // Skip the dimension that has been reduced unless keepDims is true.
        unsigned int outputIndex = 0;
        for (unsigned int i = 0; i < input.GetNumDimensions(); ++i)
        {
            if (std::find(m_Param.m_vAxis.begin(), m_Param.m_vAxis.end(), i) == m_Param.m_vAxis.end())
            {
                dimSizes[outputIndex] = armnn::numeric_cast<unsigned int>(input.GetShape()[i]);
                ++outputIndex;
            }
            else if (m_Param.m_KeepDims)
            {
                dimSizes[outputIndex] = 1;
                ++outputIndex;
            }
        }
    }
    const TensorShape& inferredShape = TensorShape(outputRank, dimSizes.data());

    ValidateAndCopyShape(outputShape, inferredShape, m_ShapeInferenceMethod, "ReduceLayer");
}

void ReduceLayer::Accept(ILayerVisitor& visitor) const
{
    visitor.VisitReduceLayer(this, GetParameters(), GetName());
}

} // namespace armnn
<|endoftext|>


<commit_before>

//#if ETH_JSONRPC && 1

#include <boost/test/unit_test.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libethrpc/EthStubServer.h>
#include <libethrpc/CorsHttpServer.h>
#include <jsonrpc/connectors/httpserver.h>
#include <jsonrpc/connectors/httpclient.h>
#include "JsonSpiritHeaders.h"
#include "TestHelper.h"
#include "ethstubclient.h"

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;

namespace jsonrpc_tests {

string name = "Ethereum(++) tests";
string dbPath;
dev::WebThreeDirect web3(name, dbPath, true);

auto_ptr<EthStubServer> jsonrpcServer;
auto_ptr<EthStubClient> jsonrpcClient;

struct JsonrpcFixture  {
    JsonrpcFixture()
    {
        cnote << "setup jsonrpc";

        web3.setIdealPeerCount(5);
        web3.ethereum()->setForceMining(true);
        jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::CorsHttpServer(8080), web3));
        jsonrpcServer->StartListening();

        jsonrpcClient = auto_ptr<EthStubClient>(new EthStubClient(new jsonrpc::HttpClient("http://localhost:8080")));
    }
    ~JsonrpcFixture()
    {
        cnote << "teardown jsonrpc";
    }
};

BOOST_GLOBAL_FIXTURE(JsonrpcFixture)

BOOST_AUTO_TEST_CASE(jsonrpc_balanceAt)
{
    cnote << "Testing jsonrpc balanceAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    string balance = jsonrpcClient->balanceAt(toJS(address), 0);
    BOOST_CHECK_EQUAL(jsToDecimal(toJS(web3.ethereum()->balanceAt(address))), balance);
}

BOOST_AUTO_TEST_CASE(jsonrpc_block)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_call)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_coinbase)
{
    cnote << "Testing jsonrpc coinbase...";
    string coinbase = jsonrpcClient->coinbase();
    BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3.ethereum()->address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_countAt)
{
    cnote << "Testing jsonrpc countAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    double countAt = jsonrpcClient->countAt(toJS(address), 0);
    BOOST_CHECK_EQUAL(countAt, (double)(uint64_t)web3.ethereum()->countAt(address, 0));
}

BOOST_AUTO_TEST_CASE(jsonrpc_defaultBlock)
{
    cnote << "Testing jsonrpc defaultBlock...";
    int defaultBlock = jsonrpcClient->defaultBlock();
    BOOST_CHECK_EQUAL(defaultBlock, web3.ethereum()->getDefault());
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromAscii)
{
    cnote << "Testing jsonrpc fromAscii...";
    string testString = "1234567890987654";
    string fromAscii = jsonrpcClient->fromAscii(32, testString);
    BOOST_CHECK_EQUAL(fromAscii, jsFromBinary(testString, 32));

}

BOOST_AUTO_TEST_CASE(jsonrpc_fromFixed)
{
    cnote << "Testing jsonrpc fromFixed...";
    string testString = "1234567890987654";
    double fromFixed = jsonrpcClient->fromFixed(testString);
    BOOST_CHECK_EQUAL(jsFromFixed(testString), fromFixed);
    BOOST_CHECK_EQUAL(testString, jsToFixed(fromFixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_gasPrice)
{
    cnote << "Testing jsonrpc gasPrice...";
    string gasPrice = jsonrpcClient->gasPrice();
    BOOST_CHECK_EQUAL(gasPrice, toJS(10 * dev::eth::szabo));
}

BOOST_AUTO_TEST_CASE(jsonrpc_isListening)
{
    //TODO
    cnote << "Testing jsonrpc isListening...";
    string testString = "1234567890987654";
}

BOOST_AUTO_TEST_CASE(jsonrpc_isMining)
{
    cnote << "Testing jsonrpc isMining...";

    web3.ethereum()->startMining();
    bool miningOn = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOn, web3.ethereum()->isMining());

    web3.ethereum()->stopMining();
    bool miningOff = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOff, web3.ethereum()->isMining());
}

BOOST_AUTO_TEST_CASE(jsonrpc_key)
{
    cnote << "Testing jsonrpc key...";
    dev::KeyPair key = KeyPair::create();
    jsonrpcServer->setKeys({key});
    string clientSecret = jsonrpcClient->key();
    jsonrpcServer->setKeys({});
    BOOST_CHECK_EQUAL(jsToSecret(clientSecret), key.secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_keys)
{
    cnote << "Testing jsonrpc keys...";
    std::vector <dev::KeyPair> keys = {KeyPair::create(), KeyPair::create()};
    jsonrpcServer->setKeys(keys);
    Json::Value k = jsonrpcClient->keys();
    jsonrpcServer->setKeys({});
    BOOST_CHECK_EQUAL(k.isArray(), true);
    BOOST_CHECK_EQUAL(k.size(),  keys.size());
    for (unsigned i = 0; i < k.size(); i++)
        BOOST_CHECK_EQUAL(jsToSecret(k[i].asString()) , keys[i].secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_lll)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_messages)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_number)
{
    cnote << "Testing jsonrpc number...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_number2)
{
    cnote << "Testing jsonrpc number2...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
    dev::eth::mine(*(web3.ethereum()), 1);
    int numberAfter = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number + 1, numberAfter);
    BOOST_CHECK_EQUAL(numberAfter, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_peerCount)
{
    cnote << "Testing jsonrpc peerCount...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_secretToAddress)
{
    cnote << "Testing jsonrpc secretToAddress...";
    dev::KeyPair pair = dev::KeyPair::create();
    string address = jsonrpcClient->secretToAddress(toJS(pair.secret()));
    BOOST_CHECK_EQUAL(jsToAddress(address), pair.address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_setListening)
{
    cnote << "Testing jsonrpc setListening...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_setMining)
{
    cnote << "Testing jsonrpc setMining...";

    jsonrpcClient->setMining(true);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), true);

    jsonrpcClient->setMining(false);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), false);
}

BOOST_AUTO_TEST_CASE(jsonrpc_sha3)
{
    cnote << "Testing jsonrpc sha3...";
    string testString = "1234567890987654";
    string sha3 = jsonrpcClient->sha3(testString);
    BOOST_CHECK_EQUAL(jsToFixed<32>(sha3), dev::eth::sha3(jsToBytes(testString)));
}

BOOST_AUTO_TEST_CASE(jsonrpc_stateAt)
{
    cnote << "Testing jsonrpc stateAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    string stateAt = jsonrpcClient->stateAt(toJS(address), 0, "0");
    BOOST_CHECK_EQUAL(toJS(web3.ethereum()->stateAt(address, jsToU256("0"), 0)), stateAt);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toAscii)
{
    cnote << "Testing jsonrpc toAscii...";
    string testString = "1234567890987654";
    string ascii = jsonrpcClient->toAscii(testString);
    BOOST_CHECK_EQUAL(jsToBinary(testString), ascii);
    BOOST_CHECK_EQUAL(testString, jsFromBinary(ascii));     // failing!
}

BOOST_AUTO_TEST_CASE(jsonrpc_toDecimal)
{
    cnote << "Testing jsonrpc toDecimal...";
    string testString = "1234567890987654";
    string decimal = jsonrpcClient->toDecimal(testString);
    BOOST_CHECK_EQUAL(jsToDecimal(testString), decimal);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toFixed)
{
    cnote << "Testing jsonrpc toFixed...";
    double testValue = 123567;
    string fixed = jsonrpcClient->toFixed(testValue);
    BOOST_CHECK_EQUAL(jsToFixed(testValue), fixed);
    BOOST_CHECK_EQUAL(testValue, jsFromFixed(fixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_transact)
{
    cnote << "Testing jsonrpc transact...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    auto receiver = KeyPair::create();

    web3.ethereum()->setAddress(address);
    dev::eth::mine(*(web3.ethereum()), 1);
    auto balance = web3.ethereum()->balanceAt(address, 0);
    BOOST_REQUIRE(balance > 0);
    auto txAmount = balance / 2u;
    auto gasPrice = 10 * dev::eth::szabo;
    auto gas = dev::eth::c_txGas;

    Json::Value t;
    t["from"] = toJS(key.secret());
    t["value"] = toJS(txAmount);
    t["to"] = toJS(receiver.address());
    t["data"] = toJS(bytes());
    t["gas"] = toJS(gas);
    t["gasPrice"] = toJS(gasPrice);

    jsonrpcClient->transact(t);

    dev::eth::mine(*(web3.ethereum()), 1);
    auto balance2 = web3.ethereum()->balanceAt(receiver.address());
    BOOST_REQUIRE(balance2 > 0);
    BOOST_CHECK_EQUAL(txAmount, balance2);
}

BOOST_AUTO_TEST_CASE(jsonrpc_transaction)
{

}

BOOST_AUTO_TEST_CASE(jsonrpc_uncle)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_watch)
{

}

}

//#endif

<commit_msg>common changes<commit_after>

#if ETH_JSONRPC && 1

#include <boost/test/unit_test.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libethrpc/EthStubServer.h>
#include <libethrpc/CorsHttpServer.h>
#include <jsonrpc/connectors/httpserver.h>
#include <jsonrpc/connectors/httpclient.h>
#include "JsonSpiritHeaders.h"
#include "TestHelper.h"
#include "ethstubclient.h"

using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;

namespace jsonrpc_tests {

string name = "Ethereum(++) tests";
string dbPath;
dev::WebThreeDirect web3(name, dbPath, true);

auto_ptr<EthStubServer> jsonrpcServer;
auto_ptr<EthStubClient> jsonrpcClient;

struct JsonrpcFixture  {
    JsonrpcFixture()
    {
        cnote << "setup jsonrpc";

        web3.setIdealPeerCount(5);
        web3.ethereum()->setForceMining(true);
        jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::CorsHttpServer(8080), web3));
        jsonrpcServer->StartListening();

        jsonrpcClient = auto_ptr<EthStubClient>(new EthStubClient(new jsonrpc::HttpClient("http://localhost:8080")));
    }
    ~JsonrpcFixture()
    {
        cnote << "teardown jsonrpc";
    }
};

BOOST_GLOBAL_FIXTURE(JsonrpcFixture)

BOOST_AUTO_TEST_CASE(jsonrpc_balanceAt)
{
    cnote << "Testing jsonrpc balanceAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    string balance = jsonrpcClient->balanceAt(toJS(address), 0);
    BOOST_CHECK_EQUAL(jsToDecimal(toJS(web3.ethereum()->balanceAt(address))), balance);
}

BOOST_AUTO_TEST_CASE(jsonrpc_block)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_call)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_coinbase)
{
    cnote << "Testing jsonrpc coinbase...";
    string coinbase = jsonrpcClient->coinbase();
    BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3.ethereum()->address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_countAt)
{
    cnote << "Testing jsonrpc countAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    double countAt = jsonrpcClient->countAt(toJS(address), 0);
    BOOST_CHECK_EQUAL(countAt, (double)(uint64_t)web3.ethereum()->countAt(address, 0));
}

BOOST_AUTO_TEST_CASE(jsonrpc_defaultBlock)
{
    cnote << "Testing jsonrpc defaultBlock...";
    int defaultBlock = jsonrpcClient->defaultBlock();
    BOOST_CHECK_EQUAL(defaultBlock, web3.ethereum()->getDefault());
}

BOOST_AUTO_TEST_CASE(jsonrpc_fromAscii)
{
    cnote << "Testing jsonrpc fromAscii...";
    string testString = "1234567890987654";
    string fromAscii = jsonrpcClient->fromAscii(32, testString);
    BOOST_CHECK_EQUAL(fromAscii, jsFromBinary(testString, 32));

}

BOOST_AUTO_TEST_CASE(jsonrpc_fromFixed)
{
    cnote << "Testing jsonrpc fromFixed...";
    string testString = "1234567890987654";
    double fromFixed = jsonrpcClient->fromFixed(testString);
    BOOST_CHECK_EQUAL(jsFromFixed(testString), fromFixed);
    BOOST_CHECK_EQUAL(testString, jsToFixed(fromFixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_gasPrice)
{
    cnote << "Testing jsonrpc gasPrice...";
    string gasPrice = jsonrpcClient->gasPrice();
    BOOST_CHECK_EQUAL(gasPrice, toJS(10 * dev::eth::szabo));
}

BOOST_AUTO_TEST_CASE(jsonrpc_isListening)
{
    //TODO
    cnote << "Testing jsonrpc isListening...";
    string testString = "1234567890987654";
}

BOOST_AUTO_TEST_CASE(jsonrpc_isMining)
{
    cnote << "Testing jsonrpc isMining...";

    web3.ethereum()->startMining();
    bool miningOn = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOn, web3.ethereum()->isMining());

    web3.ethereum()->stopMining();
    bool miningOff = jsonrpcClient->isMining();
    BOOST_CHECK_EQUAL(miningOff, web3.ethereum()->isMining());
}

BOOST_AUTO_TEST_CASE(jsonrpc_key)
{
    cnote << "Testing jsonrpc key...";
    dev::KeyPair key = KeyPair::create();
    jsonrpcServer->setKeys({key});
    string clientSecret = jsonrpcClient->key();
    jsonrpcServer->setKeys({});
    BOOST_CHECK_EQUAL(jsToSecret(clientSecret), key.secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_keys)
{
    cnote << "Testing jsonrpc keys...";
    std::vector <dev::KeyPair> keys = {KeyPair::create(), KeyPair::create()};
    jsonrpcServer->setKeys(keys);
    Json::Value k = jsonrpcClient->keys();
    jsonrpcServer->setKeys({});
    BOOST_CHECK_EQUAL(k.isArray(), true);
    BOOST_CHECK_EQUAL(k.size(),  keys.size());
    for (unsigned i = 0; i < k.size(); i++)
        BOOST_CHECK_EQUAL(jsToSecret(k[i].asString()) , keys[i].secret());
}

BOOST_AUTO_TEST_CASE(jsonrpc_lll)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_messages)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_number)
{
    cnote << "Testing jsonrpc number...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_number2)
{
    cnote << "Testing jsonrpc number2...";
    int number = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number, web3.ethereum()->number() + 1);
    dev::eth::mine(*(web3.ethereum()), 1);
    int numberAfter = jsonrpcClient->number();
    BOOST_CHECK_EQUAL(number + 1, numberAfter);
    BOOST_CHECK_EQUAL(numberAfter, web3.ethereum()->number() + 1);
}

BOOST_AUTO_TEST_CASE(jsonrpc_peerCount)
{
    cnote << "Testing jsonrpc peerCount...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_secretToAddress)
{
    cnote << "Testing jsonrpc secretToAddress...";
    dev::KeyPair pair = dev::KeyPair::create();
    string address = jsonrpcClient->secretToAddress(toJS(pair.secret()));
    BOOST_CHECK_EQUAL(jsToAddress(address), pair.address());
}

BOOST_AUTO_TEST_CASE(jsonrpc_setListening)
{
    cnote << "Testing jsonrpc setListening...";
    //TODO
}

BOOST_AUTO_TEST_CASE(jsonrpc_setMining)
{
    cnote << "Testing jsonrpc setMining...";

    jsonrpcClient->setMining(true);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), true);

    jsonrpcClient->setMining(false);
    BOOST_CHECK_EQUAL(web3.ethereum()->isMining(), false);
}

BOOST_AUTO_TEST_CASE(jsonrpc_sha3)
{
    cnote << "Testing jsonrpc sha3...";
    string testString = "1234567890987654";
    string sha3 = jsonrpcClient->sha3(testString);
    BOOST_CHECK_EQUAL(jsToFixed<32>(sha3), dev::eth::sha3(jsToBytes(testString)));
}

BOOST_AUTO_TEST_CASE(jsonrpc_stateAt)
{
    cnote << "Testing jsonrpc stateAt...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    string stateAt = jsonrpcClient->stateAt(toJS(address), 0, "0");
    BOOST_CHECK_EQUAL(toJS(web3.ethereum()->stateAt(address, jsToU256("0"), 0)), stateAt);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toAscii)
{
    cnote << "Testing jsonrpc toAscii...";
    string testString = "1234567890987654";
    string ascii = jsonrpcClient->toAscii(testString);
    BOOST_CHECK_EQUAL(jsToBinary(testString), ascii);
    BOOST_CHECK_EQUAL(testString, jsFromBinary(ascii));     // failing!
}

BOOST_AUTO_TEST_CASE(jsonrpc_toDecimal)
{
    cnote << "Testing jsonrpc toDecimal...";
    string testString = "1234567890987654";
    string decimal = jsonrpcClient->toDecimal(testString);
    BOOST_CHECK_EQUAL(jsToDecimal(testString), decimal);
}

BOOST_AUTO_TEST_CASE(jsonrpc_toFixed)
{
    cnote << "Testing jsonrpc toFixed...";
    double testValue = 123567;
    string fixed = jsonrpcClient->toFixed(testValue);
    BOOST_CHECK_EQUAL(jsToFixed(testValue), fixed);
    BOOST_CHECK_EQUAL(testValue, jsFromFixed(fixed));
}

BOOST_AUTO_TEST_CASE(jsonrpc_transact)
{
    cnote << "Testing jsonrpc transact...";
    dev::KeyPair key = KeyPair::create();
    auto address = key.address();
    auto receiver = KeyPair::create();

    web3.ethereum()->setAddress(address);
    dev::eth::mine(*(web3.ethereum()), 1);
    auto balance = web3.ethereum()->balanceAt(address, 0);
    BOOST_REQUIRE(balance > 0);
    auto txAmount = balance / 2u;
    auto gasPrice = 10 * dev::eth::szabo;
    auto gas = dev::eth::c_txGas;

    Json::Value t;
    t["from"] = toJS(key.secret());
    t["value"] = toJS(txAmount);
    t["to"] = toJS(receiver.address());
    t["data"] = toJS(bytes());
    t["gas"] = toJS(gas);
    t["gasPrice"] = toJS(gasPrice);

    jsonrpcClient->transact(t);

    dev::eth::mine(*(web3.ethereum()), 1);
    auto balance2 = web3.ethereum()->balanceAt(receiver.address());
    auto number = web3.ethereum()->number();
    BOOST_REQUIRE(balance2 > 0);
    BOOST_CHECK_EQUAL(txAmount, balance2);

    //    auto ax = jsToFixed(number);
    //    Json::Value p = jsonrpcClient->transaction(0, jsToFixed(number));
    // TODO, check transactions
}

BOOST_AUTO_TEST_CASE(jsonrpc_transaction)
{

}

BOOST_AUTO_TEST_CASE(jsonrpc_uncle)
{
}

BOOST_AUTO_TEST_CASE(jsonrpc_watch)
{

}

}

#endif

<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "EventDevice.hpp"
#include "InputSystemLinux.hpp"
#include "input/KeyboardDevice.hpp"
#include "input/GamepadDevice.hpp"
#include "input/MouseDevice.hpp"
#include "input/TouchpadDevice.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"

static const uint32_t BITS_PER_LONG = 8 * sizeof(long);
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)

static inline bool isBitSet(const unsigned long* array, int bit)
{
    return (array[bit / BITS_PER_LONG] & (1LL << (bit % BITS_PER_LONG))) != 0;
}

namespace ouzel
{
    namespace input
    {
        EventDevice::EventDevice(InputSystemLinux& inputSystem, const std::string& initFilename):
            filename(initFilename)
        {
            fd = open(filename.c_str(), O_RDONLY);

            if (fd == -1)
                throw SystemError("Failed to open device file");

            if (ioctl(fd, EVIOCGRAB, 1) == -1)
                Log(Log::Level::WARN) << "Failed to grab device";

            char deviceName[256];
            if (ioctl(fd, EVIOCGNAME(sizeof(deviceName) - 1), deviceName) == -1)
                Log(Log::Level::WARN) << "Failed to get device name";
            else
            {
                name = deviceName;
                Log(Log::Level::INFO) << "Got device: " << name;
            }

            unsigned long eventBits[BITS_TO_LONGS(EV_CNT)];
            unsigned long absBits[BITS_TO_LONGS(ABS_CNT)];
            unsigned long relBits[BITS_TO_LONGS(REL_CNT)];
            unsigned long keyBits[BITS_TO_LONGS(KEY_CNT)];

            if (ioctl(fd, EVIOCGBIT(0, sizeof(eventBits)), eventBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) == -1)
                throw SystemError("Failed to get device event bits");

            if (isBitSet(eventBits, EV_KEY) && (
                    isBitSet(keyBits, KEY_1) ||
                    isBitSet(keyBits, KEY_2) ||
                    isBitSet(keyBits, KEY_3) ||
                    isBitSet(keyBits, KEY_4) ||
                    isBitSet(keyBits, KEY_5) ||
                    isBitSet(keyBits, KEY_6) ||
                    isBitSet(keyBits, KEY_7) ||
                    isBitSet(keyBits, KEY_8) ||
                    isBitSet(keyBits, KEY_9) ||
                    isBitSet(keyBits, KEY_0)
                ))
                keyboardDevice.reset(new KeyboardDevice(inputSystem, inputSystem.getNextDeviceId()));

            if (isBitSet(eventBits, EV_ABS) && isBitSet(absBits, ABS_X) && isBitSet(absBits, ABS_Y))
            {
                if ((isBitSet(keyBits, BTN_STYLUS) || isBitSet(keyBits, BTN_TOOL_PEN)) || // tablet
                    (isBitSet(keyBits, BTN_TOOL_FINGER) && !isBitSet(keyBits, BTN_TOOL_PEN)) || // touchpad
                    isBitSet(keyBits, BTN_TOUCH)) // touchscreen
                {
                    touchpadDevice.reset(new TouchpadDevice(inputSystem, inputSystem.getNextDeviceId()));

                    input_absinfo info;

                    if (ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchSlots.resize(info.maximum + 1);

                    if (ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchMinX = info.minimum;
                    touchMaxX = info.maximum;
                    touchRangeX = touchMaxX - touchMinX;

                    if (ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchMinY = info.minimum;
                    touchMaxY = info.maximum;
                    touchRangeY = touchMaxY - touchMinY;
                }
                else if (isBitSet(keyBits, BTN_MOUSE)) // mouse
                    mouseDevice.reset(new MouseDevice(inputSystem, inputSystem.getNextDeviceId()));

            }
            else if (isBitSet(eventBits, EV_REL) && isBitSet(relBits, REL_X) && isBitSet(relBits, REL_Y))
            {
                if (isBitSet(keyBits, BTN_MOUSE))
                    mouseDevice.reset(new MouseDevice(inputSystem, inputSystem.getNextDeviceId()));
            }

            if (isBitSet(keyBits, BTN_JOYSTICK) || // joystick
                isBitSet(keyBits, BTN_GAMEPAD)) // gamepad
                gamepadDevice.reset(new GamepadDevice(inputSystem, inputSystem.getNextDeviceId()));

            struct input_id id;
            ioctl(fd, EVIOCGID, &id);
            vendor = id.vendor;
            product = id.product;
        }

        EventDevice::~EventDevice()
        {
            if (fd != -1)
            {
                if (ioctl(fd, EVIOCGRAB, 0) == -1)
                    Log(Log::Level::WARN) << "Failed to release device";

                close(fd);
            }
        }

        void EventDevice::update()
        {
            input_event events[32];
            ssize_t bytesRead = read(fd, events, sizeof(events));

            if (bytesRead == -1)
                throw SystemError("Failed to read from " + filename); // TODO: disconnect the device

            int count = bytesRead / sizeof(input_event);

            for (int i = 0; i < count; ++i)
            {
                input_event& event = events[i];

                if (keyboardDevice)
                {
                    switch (event.type)
                    {
                        case EV_KEY:
                            if (event.value == 1 || event.value == 2) // press or repeat
                                keyboardDevice->handleKeyPress(InputSystemLinux::convertKeyCode(event.code));
                            else if (event.value == 0) // release
                                keyboardDevice->handleKeyRelease(InputSystemLinux::convertKeyCode(event.code));
                            break;
                    }
                }
                if (mouseDevice)
                {
                    switch (event.type)
                    {
                        case EV_ABS:
                        {
                            switch (event.code)
                            {
                                case ABS_X:
                                    cursorPosition.x = engine->getWindow()->convertWindowToNormalizedLocation(Vector2(static_cast<float>(event.value), 0.0F)).x;
                                    break;
                                case ABS_Y:
                                    cursorPosition.y = engine->getWindow()->convertWindowToNormalizedLocation(Vector2(0.0F, static_cast<float>(event.value))).y;
                                    break;
                            }

                            mouseDevice->handleMove(cursorPosition);
                            break;
                        }
                        case EV_REL:
                        {
                            Vector2 relativePos;

                            switch (event.code)
                            {
                                case REL_X:
                                    relativePos.x = static_cast<float>(event.value);
                                    break;
                                case REL_Y:
                                    relativePos.y = static_cast<float>(event.value);
                                    break;
                                case REL_WHEEL:
                                    mouseDevice->handleScroll(Vector2(0.0F, static_cast<float>(event.value)), cursorPosition);
                                    break;
                                case REL_HWHEEL:
                                    mouseDevice->handleScroll(Vector2(static_cast<float>(event.value), 0.0F), cursorPosition);
                                    break;
                            }

                            mouseDevice->handleRelativeMove(engine->getWindow()->convertWindowToNormalizedLocation(relativePos));
                            break;
                        }
                        case EV_KEY:
                        {
                            Mouse::Button button = Mouse::Button::NONE;

                            switch (event.code)
                            {
                            case BTN_LEFT:
                                button = Mouse::Button::LEFT;
                                break;
                            case BTN_RIGHT:
                                button = Mouse::Button::RIGHT;
                                break;
                            case BTN_MIDDLE:
                                button = Mouse::Button::MIDDLE;
                                break;
                            }

                            if (event.value == 1)
                                mouseDevice->handleButtonPress(button, cursorPosition);
                            else if (event.value == 0)
                                mouseDevice->handleButtonRelease(button, cursorPosition);
                            break;
                        }
                    }
                }
                if (touchpadDevice)
                {
                    switch (event.type)
                    {
                        case EV_ABS:
                        {
                            switch (event.code)
                            {
                                case ABS_MT_SLOT:
                                {
                                    currentTouchSlot = event.value;
                                    break;
                                }
                                case ABS_MT_TRACKING_ID:
                                {
                                    if (event.value >= 0)
                                    {
                                        touchSlots[currentTouchSlot].trackingId = event.value;
                                        touchSlots[currentTouchSlot].action = Slot::Action::BEGIN;
                                    }
                                    else
                                        touchSlots[currentTouchSlot].action = Slot::Action::END;
                                    break;
                                }
                                case ABS_MT_POSITION_X:
                                {
                                    touchSlots[currentTouchSlot].positionX = event.value;
                                    touchSlots[currentTouchSlot].action = Slot::Action::MOVE;
                                    break;
                                }
                                case ABS_MT_POSITION_Y:
                                {
                                    touchSlots[currentTouchSlot].positionY = event.value;
                                    touchSlots[currentTouchSlot].action = Slot::Action::MOVE;
                                    break;
                                }
                            }
                            break;
                        }
                        case EV_SYN:
                        {
                            switch (event.code)
                            {
                                case SYN_REPORT:
                                {
                                    for (Slot& slot : touchSlots)
                                    {
                                        if (slot.action != Slot::Action::NONE)
                                        {
                                            Vector2 position(static_cast<float>(slot.positionX - touchMinX) / touchRangeX,
                                                             static_cast<float>(slot.positionY - touchMinY) / touchRangeY);

                                            switch (slot.action)
                                            {
                                                case Slot::Action::NONE:
                                                    break;
                                                case Slot::Action::BEGIN:
                                                    touchpadDevice->handleTouchBegin(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                                case Slot::Action::END:
                                                    touchpadDevice->handleTouchEnd(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                                case Slot::Action::MOVE:
                                                    touchpadDevice->handleTouchMove(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                            }

                                            slot.action = Slot::Action::NONE;
                                        }
                                    }
                                    break;
                                }
                                case SYN_DROPPED:
                                {
                                    for (Slot& slot : touchSlots)
                                        slot.action = Slot::Action::NONE;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
                if (gamepadDevice)
                {
                    switch(event.type)
                    {
                        case EV_ABS:
                        {
                            // TODO: implement
                            break;
                        }
                        case EV_REL:
                        {
                            // TODO: implement
                            break;
                        }
                        case EV_KEY:
                        {
                            // TODO: implement
                            break;
                        }
                    }
                }
            }
        }
    } // namespace input
} // namespace ouzel
<commit_msg>Handle SYN_DROPPED<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "EventDevice.hpp"
#include "InputSystemLinux.hpp"
#include "input/KeyboardDevice.hpp"
#include "input/GamepadDevice.hpp"
#include "input/MouseDevice.hpp"
#include "input/TouchpadDevice.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"

static const uint32_t BITS_PER_LONG = 8 * sizeof(long);
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)

static inline bool isBitSet(const unsigned long* array, int bit)
{
    return (array[bit / BITS_PER_LONG] & (1LL << (bit % BITS_PER_LONG))) != 0;
}

namespace ouzel
{
    namespace input
    {
        EventDevice::EventDevice(InputSystemLinux& inputSystem, const std::string& initFilename):
            filename(initFilename)
        {
            fd = open(filename.c_str(), O_RDONLY);

            if (fd == -1)
                throw SystemError("Failed to open device file");

            if (ioctl(fd, EVIOCGRAB, 1) == -1)
                Log(Log::Level::WARN) << "Failed to grab device";

            char deviceName[256];
            if (ioctl(fd, EVIOCGNAME(sizeof(deviceName) - 1), deviceName) == -1)
                Log(Log::Level::WARN) << "Failed to get device name";
            else
            {
                name = deviceName;
                Log(Log::Level::INFO) << "Got device: " << name;
            }

            unsigned long eventBits[BITS_TO_LONGS(EV_CNT)];
            unsigned long absBits[BITS_TO_LONGS(ABS_CNT)];
            unsigned long relBits[BITS_TO_LONGS(REL_CNT)];
            unsigned long keyBits[BITS_TO_LONGS(KEY_CNT)];

            if (ioctl(fd, EVIOCGBIT(0, sizeof(eventBits)), eventBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits) == -1 ||
                ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) == -1)
                throw SystemError("Failed to get device event bits");

            if (isBitSet(eventBits, EV_KEY) && (
                    isBitSet(keyBits, KEY_1) ||
                    isBitSet(keyBits, KEY_2) ||
                    isBitSet(keyBits, KEY_3) ||
                    isBitSet(keyBits, KEY_4) ||
                    isBitSet(keyBits, KEY_5) ||
                    isBitSet(keyBits, KEY_6) ||
                    isBitSet(keyBits, KEY_7) ||
                    isBitSet(keyBits, KEY_8) ||
                    isBitSet(keyBits, KEY_9) ||
                    isBitSet(keyBits, KEY_0)
                ))
                keyboardDevice.reset(new KeyboardDevice(inputSystem, inputSystem.getNextDeviceId()));

            if (isBitSet(eventBits, EV_ABS) && isBitSet(absBits, ABS_X) && isBitSet(absBits, ABS_Y))
            {
                if ((isBitSet(keyBits, BTN_STYLUS) || isBitSet(keyBits, BTN_TOOL_PEN)) || // tablet
                    (isBitSet(keyBits, BTN_TOOL_FINGER) && !isBitSet(keyBits, BTN_TOOL_PEN)) || // touchpad
                    isBitSet(keyBits, BTN_TOUCH)) // touchscreen
                {
                    touchpadDevice.reset(new TouchpadDevice(inputSystem, inputSystem.getNextDeviceId()));

                    input_absinfo info;

                    if (ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchSlots.resize(info.maximum + 1);

                    if (ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchMinX = info.minimum;
                    touchMaxX = info.maximum;
                    touchRangeX = touchMaxX - touchMinX;

                    if (ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), &info) == -1)
                        throw SystemError("Failed to get device info");

                    touchMinY = info.minimum;
                    touchMaxY = info.maximum;
                    touchRangeY = touchMaxY - touchMinY;
                }
                else if (isBitSet(keyBits, BTN_MOUSE)) // mouse
                    mouseDevice.reset(new MouseDevice(inputSystem, inputSystem.getNextDeviceId()));

            }
            else if (isBitSet(eventBits, EV_REL) && isBitSet(relBits, REL_X) && isBitSet(relBits, REL_Y))
            {
                if (isBitSet(keyBits, BTN_MOUSE))
                    mouseDevice.reset(new MouseDevice(inputSystem, inputSystem.getNextDeviceId()));
            }

            if (isBitSet(keyBits, BTN_JOYSTICK) || // joystick
                isBitSet(keyBits, BTN_GAMEPAD)) // gamepad
                gamepadDevice.reset(new GamepadDevice(inputSystem, inputSystem.getNextDeviceId()));

            struct input_id id;
            ioctl(fd, EVIOCGID, &id);
            vendor = id.vendor;
            product = id.product;
        }

        EventDevice::~EventDevice()
        {
            if (fd != -1)
            {
                if (ioctl(fd, EVIOCGRAB, 0) == -1)
                    Log(Log::Level::WARN) << "Failed to release device";

                close(fd);
            }
        }

        void EventDevice::update()
        {
            input_event events[32];
            ssize_t bytesRead = read(fd, events, sizeof(events));

            if (bytesRead == -1)
                throw SystemError("Failed to read from " + filename); // TODO: disconnect the device

            int count = bytesRead / sizeof(input_event);

            for (int i = 0; i < count; ++i)
            {
                input_event& event = events[i];

                if (keyboardDevice)
                {
                    switch (event.type)
                    {
                        case EV_KEY:
                            if (event.value == 1 || event.value == 2) // press or repeat
                                keyboardDevice->handleKeyPress(InputSystemLinux::convertKeyCode(event.code));
                            else if (event.value == 0) // release
                                keyboardDevice->handleKeyRelease(InputSystemLinux::convertKeyCode(event.code));
                            break;
                    }
                }
                if (mouseDevice)
                {
                    switch (event.type)
                    {
                        case EV_ABS:
                        {
                            switch (event.code)
                            {
                                case ABS_X:
                                    cursorPosition.x = engine->getWindow()->convertWindowToNormalizedLocation(Vector2(static_cast<float>(event.value), 0.0F)).x;
                                    break;
                                case ABS_Y:
                                    cursorPosition.y = engine->getWindow()->convertWindowToNormalizedLocation(Vector2(0.0F, static_cast<float>(event.value))).y;
                                    break;
                            }

                            mouseDevice->handleMove(cursorPosition);
                            break;
                        }
                        case EV_REL:
                        {
                            Vector2 relativePos;

                            switch (event.code)
                            {
                                case REL_X:
                                    relativePos.x = static_cast<float>(event.value);
                                    break;
                                case REL_Y:
                                    relativePos.y = static_cast<float>(event.value);
                                    break;
                                case REL_WHEEL:
                                    mouseDevice->handleScroll(Vector2(0.0F, static_cast<float>(event.value)), cursorPosition);
                                    break;
                                case REL_HWHEEL:
                                    mouseDevice->handleScroll(Vector2(static_cast<float>(event.value), 0.0F), cursorPosition);
                                    break;
                            }

                            mouseDevice->handleRelativeMove(engine->getWindow()->convertWindowToNormalizedLocation(relativePos));
                            break;
                        }
                        case EV_KEY:
                        {
                            Mouse::Button button = Mouse::Button::NONE;

                            switch (event.code)
                            {
                            case BTN_LEFT:
                                button = Mouse::Button::LEFT;
                                break;
                            case BTN_RIGHT:
                                button = Mouse::Button::RIGHT;
                                break;
                            case BTN_MIDDLE:
                                button = Mouse::Button::MIDDLE;
                                break;
                            }

                            if (event.value == 1)
                                mouseDevice->handleButtonPress(button, cursorPosition);
                            else if (event.value == 0)
                                mouseDevice->handleButtonRelease(button, cursorPosition);
                            break;
                        }
                    }
                }
                if (touchpadDevice)
                {
                    switch (event.type)
                    {
                        case EV_ABS:
                        {
                            switch (event.code)
                            {
                                case ABS_MT_SLOT:
                                {
                                    currentTouchSlot = event.value;
                                    break;
                                }
                                case ABS_MT_TRACKING_ID:
                                {
                                    if (event.value >= 0)
                                    {
                                        touchSlots[currentTouchSlot].trackingId = event.value;
                                        touchSlots[currentTouchSlot].action = Slot::Action::BEGIN;
                                    }
                                    else
                                        touchSlots[currentTouchSlot].action = Slot::Action::END;
                                    break;
                                }
                                case ABS_MT_POSITION_X:
                                {
                                    touchSlots[currentTouchSlot].positionX = event.value;
                                    touchSlots[currentTouchSlot].action = Slot::Action::MOVE;
                                    break;
                                }
                                case ABS_MT_POSITION_Y:
                                {
                                    touchSlots[currentTouchSlot].positionY = event.value;
                                    touchSlots[currentTouchSlot].action = Slot::Action::MOVE;
                                    break;
                                }
                            }
                            break;
                        }
                        case EV_SYN:
                        {
                            switch (event.code)
                            {
                                case SYN_REPORT:
                                {
                                    for (Slot& slot : touchSlots)
                                    {
                                        if (slot.action != Slot::Action::NONE)
                                        {
                                            Vector2 position(static_cast<float>(slot.positionX - touchMinX) / touchRangeX,
                                                             static_cast<float>(slot.positionY - touchMinY) / touchRangeY);

                                            switch (slot.action)
                                            {
                                                case Slot::Action::NONE:
                                                    break;
                                                case Slot::Action::BEGIN:
                                                    touchpadDevice->handleTouchBegin(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                                case Slot::Action::END:
                                                    touchpadDevice->handleTouchEnd(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                                case Slot::Action::MOVE:
                                                    touchpadDevice->handleTouchMove(static_cast<uint64_t>(slot.trackingId), position, 1.0F);
                                                    break;
                                            }

                                            slot.action = Slot::Action::NONE;
                                        }
                                    }
                                    break;
                                }
                                case SYN_DROPPED:
                                {
                                    struct input_mt_request_layout
                                    {
                                        __u32 code;
                                        __s32 values[1];
                                    };

                                    size_t size = sizeof(__u32) + sizeof(__s32) * touchSlots.size();
                                    std::vector<uint8_t> data(size);

                                    input_mt_request_layout* request = reinterpret_cast<input_mt_request_layout*>(data.data());

                                    request->code = ABS_MT_TRACKING_ID;
                                    if (ioctl(fd, EVIOCGMTSLOTS(size), request) == -1)
                                        throw SystemError("Failed to get device info");

                                    for (size_t i = 0; i < touchSlots.size(); ++i)
                                    {
                                        if (touchSlots[i].trackingId < 0 &&
                                            request->values[i] >= 0)
                                        {
                                            touchSlots[i].trackingId = request->values[i];
                                            touchSlots[i].action = Slot::Action::BEGIN;
                                        }
                                        else if (touchSlots[i].trackingId >= 0 &&
                                                 request->values[i] < 0)
                                        {
                                            touchSlots[i].trackingId = request->values[i];
                                            touchSlots[i].action = Slot::Action::END;
                                        }
                                    }

                                    request->code = ABS_MT_POSITION_X;
                                    if (ioctl(fd, EVIOCGMTSLOTS(size), request) == -1)
                                        throw SystemError("Failed to get device info");

                                    for (size_t i = 0; i < touchSlots.size(); ++i)
                                    {
                                        if (touchSlots[i].trackingId >= 0 &&
                                            touchSlots[i].positionX != request->values[i])
                                        {
                                            touchSlots[i].positionX = request->values[i];
                                            if (touchSlots[i].action == Slot::Action::NONE)
                                                touchSlots[i].action = Slot::Action::MOVE;
                                        }
                                    }

                                    request->code = ABS_MT_POSITION_Y;
                                    if (ioctl(fd, EVIOCGMTSLOTS(size), request) == -1)
                                        throw SystemError("Failed to get device info");

                                    for (size_t i = 0; i < touchSlots.size(); ++i)
                                    {
                                        if (touchSlots[i].trackingId >= 0 &&
                                            touchSlots[i].positionY != request->values[i])
                                        {
                                            touchSlots[i].positionY = request->values[i];
                                            if (touchSlots[i].action == Slot::Action::NONE)
                                                touchSlots[i].action = Slot::Action::MOVE;
                                        }
                                    }

                                    input_absinfo info;
                                    if (ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info) == -1)
                                        throw SystemError("Failed to get device info");
                                    currentTouchSlot = info.value;

                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
                if (gamepadDevice)
                {
                    switch(event.type)
                    {
                        case EV_ABS:
                        {
                            // TODO: implement
                            break;
                        }
                        case EV_REL:
                        {
                            // TODO: implement
                            break;
                        }
                        case EV_KEY:
                        {
                            // TODO: implement
                            break;
                        }
                    }
                }
            }
        }
    } // namespace input
} // namespace ouzel
<|endoftext|>


<commit_before><commit_msg>fix creation of substreams for OLE2<commit_after><|endoftext|>