<commit_before>/*************************************************************************
 *
 *  $RCSfile: pyuno_loader.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-24 14:24:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Ralph Thomas
 *
 *   Copyright: 2000 by Sun Microsystems, Inc.
 *
 *   All Rights Reserved.
 *
 *   Contributor(s): Ralph Thomas, Joerg Budischewski
 *
 *
 ************************************************************************/
#include <osl/module.hxx>
#include <osl/process.h>
#include <osl/file.h>
#include <osl/thread.h>

#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/bootstrap.hxx>

#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/factory.hxx>

#include <pyuno/pyuno.hxx>

using rtl::OUString;
using rtl::OUStringBuffer;
using rtl::OString;

using pyuno::PyRef;
using pyuno::Runtime;
using pyuno::PyThreadAttach;

using com::sun::star::registry::XRegistryKey;
using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::XComponentContext;
using com::sun::star::uno::RuntimeException;

namespace pyuno_loader
{

static void raiseRuntimeExceptionWhenNeeded() throw ( RuntimeException )
{
    if( PyErr_Occurred() )
    {
        PyRef excType, excValue, excTraceback;
        PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
        Runtime runtime;
        com::sun::star::uno::Any a = runtime.extractUnoException( excType, excValue, excTraceback );
        OUStringBuffer buf;
        buf.appendAscii( "python-loader:" );
        if( a.hasValue() )
            buf.append( ((com::sun::star::uno::Exception *)a.getValue())->Message );
        throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
    }
}

static PyRef getLoaderModule() throw( RuntimeException )
{
    PyRef module( PyImport_ImportModule( "pythonloader" ), SAL_NO_ACQUIRE );
    raiseRuntimeExceptionWhenNeeded();
    if( !module.is() )
    {
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pythonloader: Couldn't load pythonloader module" ) ),
            Reference< XInterface > () );
    }
    return PyRef( PyModule_GetDict( module.get() ));
}

static PyRef getObjectFromLoaderModule( const char * func )
    throw ( RuntimeException )
{
    PyRef object( PyDict_GetItemString(getLoaderModule().get(), (char*)func ) );
    if( !object.is() )
    {
        OUStringBuffer buf;
        buf.appendAscii( "pythonloader: couldn't find core element pythonloader." );
        buf.appendAscii( func );
        throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >());
    }
    return object;
}

OUString getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.pyuno.Loader" ) );
}

Sequence< OUString > getSupportedServiceNames()
{
    OUString serviceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Python" ) );
    return Sequence< OUString > ( &serviceName, 1 );
}

static OUString getLibDir()
{
    static OUString *pLibDir;
    if( !pLibDir )
    {
        osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
        if( ! pLibDir )
        {
            static OUString libDir;

            // changed from reinterpret_cast<void*> this is not allowed
            // in gcc 3.3 without permissive.  Us simple C cast.
            if( osl::Module::getUrlFromAddress( (void*)(getLibDir) , libDir ) )
            {
                libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
            }
            pLibDir = &libDir;
        }
    }
    return *pLibDir;
}

Reference< XInterface > CreateInstance( const Reference< XComponentContext > & ctx )
{
    Reference< XInterface > ret;

    if( ! Py_IsInitialized() )
    {
        // in case python path is already set, nothing is done ...
        const OUString pythonPath ( RTL_CONSTASCII_USTRINGPARAM( "PYTHONPATH" ) );

        // otherwise, try to get the PYTHONPATH bootstrap variable
        OUStringBuffer bufPYTHONPATH( 256 );
        OUString path = getLibDir();
        if( path.getLength() )
        {
            path += OUString( RTL_CONSTASCII_USTRINGPARAM( "/" SAL_CONFIGFILE("pythonloader.uno" )));
            rtl::Bootstrap bootstrap(path);

            // look for pythonhome
            OUString pythonHome;
            if( bootstrap.getFrom( OUString ( RTL_CONSTASCII_USTRINGPARAM( "PYTHONHOME") ),
                                   pythonHome ) )
            {
                osl_getFileURLFromSystemPath( pythonHome.pData, &(pythonHome.pData) );
                rtl::OStringBuffer stringBuffer( pythonHome.getLength() +20);
                stringBuffer.append( "PYTHONHOME=" );
                stringBuffer.append(
                    rtl::OUStringToOString( pythonHome, osl_getThreadTextEncoding() ) );

                OString env2= stringBuffer.makeStringAndClear();
                rtl_string_acquire(env2.pData );
                putenv( env2.pData->buffer );

            }

            // check for pythonpath
            OUString pythonPathBootstrap;
            bootstrap.getFrom( pythonPath , pythonPathBootstrap );

            sal_Int32 nIndex = 0;
            while( 1 )
            {
                sal_Int32 nNew = pythonPathBootstrap.indexOf( ' ', nIndex );
                OUString fileUrl;
                if( nNew == -1 )
                {
                    fileUrl = OUString( &( pythonPathBootstrap[nIndex] ) );
                }
                else
                {
                    fileUrl = OUString( &(pythonPathBootstrap[nIndex]) , nNew - nIndex );
                }
                OUString systemPath;
                osl_getSystemPathFromFileURL( fileUrl.pData, &(systemPath.pData) );
                bufPYTHONPATH.append( systemPath );
                if( nNew == -1 )
                    break;
                bufPYTHONPATH.append( (sal_Unicode) SAL_PATHSEPARATOR );
                nIndex = nNew + 1;
            }
        }

        OUString value;
        osl_getEnvironment( pythonPath.pData,  &value.pData );
        bufPYTHONPATH.append( value );

        rtl::OStringBuffer stringBuffer;
        stringBuffer.append( "PYTHONPATH=" );
        stringBuffer.append(
            rtl::OUStringToOString( bufPYTHONPATH.makeStringAndClear(), osl_getThreadTextEncoding()));

        OString env = stringBuffer.makeStringAndClear();

        // leak this string (putenv does not make a copy)
        rtl_string_acquire( env.pData );
        putenv( env.pData->buffer );

        // initialize python
        Py_Initialize();
        PyEval_InitThreads();

        PyThreadState *tstate = PyThreadState_Get();
        PyEval_ReleaseThread( tstate );
    }

    PyThreadAttach attach( PyInterpreterState_Head() );
    {
        if( ! Runtime::isInitialized() )
        {
            Runtime::initialize( ctx );
        }
        Runtime runtime;

        PyRef pyCtx = runtime.any2PyObject(
            com::sun::star::uno::makeAny( ctx ) );

        PyRef clazz = getObjectFromLoaderModule( "Loader" );
        PyRef args ( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
        PyTuple_SetItem( args.get(), 0 , pyCtx.getAcquired() );
        PyRef pyInstance( PyObject_CallObject( clazz.get() , args.get() ), SAL_NO_ACQUIRE );
        runtime.pyObject2Any( pyInstance ) >>= ret;
    }
    return ret;
}

}

static struct cppu::ImplementationEntry g_entries[] =
{
    {
        pyuno_loader::CreateInstance, pyuno_loader::getImplementationName,
        pyuno_loader::getSupportedServiceNames, cppu::createSingleComponentFactory,
        0 , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}

}

<commit_msg>INTEGRATION: CWS ooo19126 (1.6.12); FILE MERGED 2005/09/05 18:39:19 rt 1.6.12.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pyuno_loader.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:50:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <osl/module.hxx>
#include <osl/process.h>
#include <osl/file.h>
#include <osl/thread.h>

#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/bootstrap.hxx>

#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/factory.hxx>

#include <pyuno/pyuno.hxx>

using rtl::OUString;
using rtl::OUStringBuffer;
using rtl::OString;

using pyuno::PyRef;
using pyuno::Runtime;
using pyuno::PyThreadAttach;

using com::sun::star::registry::XRegistryKey;
using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::XComponentContext;
using com::sun::star::uno::RuntimeException;

namespace pyuno_loader
{

static void raiseRuntimeExceptionWhenNeeded() throw ( RuntimeException )
{
    if( PyErr_Occurred() )
    {
        PyRef excType, excValue, excTraceback;
        PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
        Runtime runtime;
        com::sun::star::uno::Any a = runtime.extractUnoException( excType, excValue, excTraceback );
        OUStringBuffer buf;
        buf.appendAscii( "python-loader:" );
        if( a.hasValue() )
            buf.append( ((com::sun::star::uno::Exception *)a.getValue())->Message );
        throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
    }
}

static PyRef getLoaderModule() throw( RuntimeException )
{
    PyRef module( PyImport_ImportModule( "pythonloader" ), SAL_NO_ACQUIRE );
    raiseRuntimeExceptionWhenNeeded();
    if( !module.is() )
    {
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pythonloader: Couldn't load pythonloader module" ) ),
            Reference< XInterface > () );
    }
    return PyRef( PyModule_GetDict( module.get() ));
}

static PyRef getObjectFromLoaderModule( const char * func )
    throw ( RuntimeException )
{
    PyRef object( PyDict_GetItemString(getLoaderModule().get(), (char*)func ) );
    if( !object.is() )
    {
        OUStringBuffer buf;
        buf.appendAscii( "pythonloader: couldn't find core element pythonloader." );
        buf.appendAscii( func );
        throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >());
    }
    return object;
}

OUString getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.pyuno.Loader" ) );
}

Sequence< OUString > getSupportedServiceNames()
{
    OUString serviceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Python" ) );
    return Sequence< OUString > ( &serviceName, 1 );
}

static OUString getLibDir()
{
    static OUString *pLibDir;
    if( !pLibDir )
    {
        osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
        if( ! pLibDir )
        {
            static OUString libDir;

            // changed from reinterpret_cast<void*> this is not allowed
            // in gcc 3.3 without permissive.  Us simple C cast.
            if( osl::Module::getUrlFromAddress( (void*)(getLibDir) , libDir ) )
            {
                libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
            }
            pLibDir = &libDir;
        }
    }
    return *pLibDir;
}

Reference< XInterface > CreateInstance( const Reference< XComponentContext > & ctx )
{
    Reference< XInterface > ret;

    if( ! Py_IsInitialized() )
    {
        // in case python path is already set, nothing is done ...
        const OUString pythonPath ( RTL_CONSTASCII_USTRINGPARAM( "PYTHONPATH" ) );

        // otherwise, try to get the PYTHONPATH bootstrap variable
        OUStringBuffer bufPYTHONPATH( 256 );
        OUString path = getLibDir();
        if( path.getLength() )
        {
            path += OUString( RTL_CONSTASCII_USTRINGPARAM( "/" SAL_CONFIGFILE("pythonloader.uno" )));
            rtl::Bootstrap bootstrap(path);

            // look for pythonhome
            OUString pythonHome;
            if( bootstrap.getFrom( OUString ( RTL_CONSTASCII_USTRINGPARAM( "PYTHONHOME") ),
                                   pythonHome ) )
            {
                osl_getFileURLFromSystemPath( pythonHome.pData, &(pythonHome.pData) );
                rtl::OStringBuffer stringBuffer( pythonHome.getLength() +20);
                stringBuffer.append( "PYTHONHOME=" );
                stringBuffer.append(
                    rtl::OUStringToOString( pythonHome, osl_getThreadTextEncoding() ) );

                OString env2= stringBuffer.makeStringAndClear();
                rtl_string_acquire(env2.pData );
                putenv( env2.pData->buffer );

            }

            // check for pythonpath
            OUString pythonPathBootstrap;
            bootstrap.getFrom( pythonPath , pythonPathBootstrap );

            sal_Int32 nIndex = 0;
            while( 1 )
            {
                sal_Int32 nNew = pythonPathBootstrap.indexOf( ' ', nIndex );
                OUString fileUrl;
                if( nNew == -1 )
                {
                    fileUrl = OUString( &( pythonPathBootstrap[nIndex] ) );
                }
                else
                {
                    fileUrl = OUString( &(pythonPathBootstrap[nIndex]) , nNew - nIndex );
                }
                OUString systemPath;
                osl_getSystemPathFromFileURL( fileUrl.pData, &(systemPath.pData) );
                bufPYTHONPATH.append( systemPath );
                if( nNew == -1 )
                    break;
                bufPYTHONPATH.append( (sal_Unicode) SAL_PATHSEPARATOR );
                nIndex = nNew + 1;
            }
        }

        OUString value;
        osl_getEnvironment( pythonPath.pData,  &value.pData );
        bufPYTHONPATH.append( value );

        rtl::OStringBuffer stringBuffer;
        stringBuffer.append( "PYTHONPATH=" );
        stringBuffer.append(
            rtl::OUStringToOString( bufPYTHONPATH.makeStringAndClear(), osl_getThreadTextEncoding()));

        OString env = stringBuffer.makeStringAndClear();

        // leak this string (putenv does not make a copy)
        rtl_string_acquire( env.pData );
        putenv( env.pData->buffer );

        // initialize python
        Py_Initialize();
        PyEval_InitThreads();

        PyThreadState *tstate = PyThreadState_Get();
        PyEval_ReleaseThread( tstate );
    }

    PyThreadAttach attach( PyInterpreterState_Head() );
    {
        if( ! Runtime::isInitialized() )
        {
            Runtime::initialize( ctx );
        }
        Runtime runtime;

        PyRef pyCtx = runtime.any2PyObject(
            com::sun::star::uno::makeAny( ctx ) );

        PyRef clazz = getObjectFromLoaderModule( "Loader" );
        PyRef args ( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
        PyTuple_SetItem( args.get(), 0 , pyCtx.getAcquired() );
        PyRef pyInstance( PyObject_CallObject( clazz.get() , args.get() ), SAL_NO_ACQUIRE );
        runtime.pyObject2Any( pyInstance ) >>= ret;
    }
    return ret;
}

}

static struct cppu::ImplementationEntry g_entries[] =
{
    {
        pyuno_loader::CreateInstance, pyuno_loader::getImplementationName,
        pyuno_loader::getSupportedServiceNames, cppu::createSingleComponentFactory,
        0 , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}

}

<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "braincloud/BrainCloudClient.h"
#include "TestResult.h"
#include "TestBCTournament.h"
#include "braincloud/reason_codes.h"
#include "braincloud/BrainCloudSocialLeaderboard.h"

using namespace BrainCloud;

TEST_F(TestBCTournament, ClaimTournamentReward)
{
	int32_t version = JoinTournament();

	TestResult tr;

	m_bc->getTournamentService()->claimTournamentReward(_leaderboardId, version, &tr);
	tr.runExpectFail(m_bc, 400, VIEWING_REWARD_FOR_NON_PROCESSED_TOURNAMENTS);

	LeaveTournament();
}

TEST_F(TestBCTournament, GetTournamentStatus)
{
	int32_t version = JoinTournament();

	TestResult tr;

	m_bc->getTournamentService()->getTournamentStatus(_leaderboardId, version, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, JoinTournament)
{
	JoinTournament();
	LeaveTournament();
}

TEST_F(TestBCTournament, LeaveTournament)
{
	JoinTournament();
	LeaveTournament();
}

TEST_F(TestBCTournament, PostTournamentScore)
{
	int32_t version = JoinTournament();

	TestResult tr;
	time_t t = time(0);
	struct tm * time = gmtime(&t);

	m_bc->getTournamentService()->postTournamentScore(_leaderboardId, 200, "", time, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, PostTournamentScoreWithResults)
{
	int32_t version = JoinTournament();

	TestResult tr;
	time_t t = time(0);
	struct tm * time = gmtime(&t);

	m_bc->getTournamentService()->postTournamentScoreWithResults(_leaderboardId, 200, "", time, HIGH_TO_LOW, 10, 10, 0, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, ViewCurrentReward)
{
	JoinTournament();

	TestResult tr;
	m_bc->getTournamentService()->viewCurrentReward(_leaderboardId, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, ViewReward)
{
	JoinTournament();

	TestResult tr;
	m_bc->getTournamentService()->viewReward(_leaderboardId, -1, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

int32_t TestBCTournament::JoinTournament()
{
	TestResult tr;
	m_bc->getTournamentService()->joinTournament(_leaderboardId, _tournamentCode, 100, &tr);
	tr.run(m_bc);

	m_bc->getTournamentService()->getTournamentStatus(_leaderboardId, -1, &tr);
	tr.run(m_bc);
	return tr.m_response["data"]["versionId"].asInt();
}

void TestBCTournament::LeaveTournament()
{
	TestResult tr;
	m_bc->getTournamentService()->leaveTournament(_leaderboardId, &tr);
	tr.run(m_bc);
}<commit_msg>Fix VS 2008<commit_after>#include "gtest/gtest.h"
#include "braincloud/BrainCloudClient.h"
#include "TestResult.h"
#include "TestBCTournament.h"
#include "braincloud/reason_codes.h"
#include "braincloud/BrainCloudSocialLeaderboard.h"
#include <time.h>

using namespace BrainCloud;

TEST_F(TestBCTournament, ClaimTournamentReward)
{
	int32_t version = JoinTournament();

	TestResult tr;

	m_bc->getTournamentService()->claimTournamentReward(_leaderboardId, version, &tr);
	tr.runExpectFail(m_bc, 400, VIEWING_REWARD_FOR_NON_PROCESSED_TOURNAMENTS);

	LeaveTournament();
}

TEST_F(TestBCTournament, GetTournamentStatus)
{
	int32_t version = JoinTournament();

	TestResult tr;

	m_bc->getTournamentService()->getTournamentStatus(_leaderboardId, version, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, JoinTournament)
{
	JoinTournament();
	LeaveTournament();
}

TEST_F(TestBCTournament, LeaveTournament)
{
	JoinTournament();
	LeaveTournament();
}

TEST_F(TestBCTournament, PostTournamentScore)
{
	int32_t version = JoinTournament();

	TestResult tr;
	time_t t = time(0);
	struct tm * time = gmtime(&t);

	m_bc->getTournamentService()->postTournamentScore(_leaderboardId, 200, "", time, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, PostTournamentScoreWithResults)
{
	int32_t version = JoinTournament();

	TestResult tr;
	time_t t = time(0);
	struct tm * time = gmtime(&t);

	m_bc->getTournamentService()->postTournamentScoreWithResults(_leaderboardId, 200, "", time, HIGH_TO_LOW, 10, 10, 0, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, ViewCurrentReward)
{
	JoinTournament();

	TestResult tr;
	m_bc->getTournamentService()->viewCurrentReward(_leaderboardId, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

TEST_F(TestBCTournament, ViewReward)
{
	JoinTournament();

	TestResult tr;
	m_bc->getTournamentService()->viewReward(_leaderboardId, -1, &tr);
	tr.run(m_bc);

	LeaveTournament();
}

int32_t TestBCTournament::JoinTournament()
{
	TestResult tr;
	m_bc->getTournamentService()->joinTournament(_leaderboardId, _tournamentCode, 100, &tr);
	tr.run(m_bc);

	m_bc->getTournamentService()->getTournamentStatus(_leaderboardId, -1, &tr);
	tr.run(m_bc);
	return tr.m_response["data"]["versionId"].asInt();
}

void TestBCTournament::LeaveTournament()
{
	TestResult tr;
	m_bc->getTournamentService()->leaveTournament(_leaderboardId, &tr);
	tr.run(m_bc);
}<|endoftext|>


<commit_before>#include <mart-netlib/tcp.hpp>

#include <mart-common/PrintWrappers.h>

#include <catch2/catch.hpp>

#include <future>
#include <iostream>

namespace mart::nw::ip::tcp {

std::ostream& operator<<( std::ostream& out, mart::nw::ip::tcp::endpoint ep )
{
	out << ep.toStringEx();
	return out;
}

} // namespace

TEST_CASE( "tcp_socket_simple_exchange", "[net]" )
{
	using namespace mart::nw::ip;
	tcp::endpoint e1 = { mart::nw::ip::address_any, mart::nw::ip::port_nr{ 1583 } };
	tcp::endpoint e2 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1485 } };
	tcp::endpoint e3{ "127.0.0.1:3495" };
	tcp::Socket   s1;

	tcp::Socket s2{};

	tcp::Socket s4( std::move( s1 ) );
	s2 = std::move( s4 );

	[[maybe_unused]] mart::nw::socks::RaiiSocket& raw_socket = s2.as_raii_socket();

	CHECK_NOTHROW( s2.bind( e1 ) );
	// socket can't be rebinded to a different one
	CHECK_THROWS( s2.bind( e2 ) );
	CHECK_THROWS( s2.connect( e2 ) );
	CHECK( s2.get_local_endpoint() == e1 );
	CHECK( !s2.get_remote_endpoint().valid() );

	CHECK_THROWS( s2.send( mart::view_bytes( 5 ) ) );
}

TEST_CASE( "tcp_simple_exchange", "[net]" )
{
	using namespace mart::nw::ip;
	tcp::endpoint e1 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1584 } };
	tcp::endpoint e2 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1486 } };

	auto s1_future = std::async( [&] {
		tcp::Acceptor ac( e1 );
		return ac.accept( std::chrono::milliseconds( 1000 ) );
	} );

	tcp::Socket s2;
	s2.bind( e2 );
	s2.connect( e1 );

	auto s1 = s1_future.get();
	CHECK( s1.is_valid() );

	CHECK( s2.get_remote_endpoint() == e1 );
	CHECK( s1.get_remote_endpoint() == e2 );

	const int data_orig = 0xffa1;
	int       data_rec{};
	s1.send( mart::view_bytes( data_orig ) );
	auto rec = s2.recv( mart::view_bytes_mutable( data_rec ) );

	CHECK( rec.size_inBytes() == sizeof( int ) );
	CHECK( data_orig == data_rec );

}<commit_msg>[test] Ensure acceptor runs asynchronously<commit_after>#include <mart-netlib/tcp.hpp>

#include <mart-common/PrintWrappers.h>

#include <catch2/catch.hpp>

#include <future>
#include <iostream>

namespace mart::nw::ip::tcp {

std::ostream& operator<<( std::ostream& out, mart::nw::ip::tcp::endpoint ep )
{
	out << ep.toStringEx();
	return out;
}

} // namespace

TEST_CASE( "tcp_socket_simple_exchange", "[net]" )
{
	using namespace mart::nw::ip;
	tcp::endpoint e1 = { mart::nw::ip::address_any, mart::nw::ip::port_nr{ 1583 } };
	tcp::endpoint e2 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1485 } };
	tcp::endpoint e3{ "127.0.0.1:3495" };
	tcp::Socket   s1;

	tcp::Socket s2{};

	tcp::Socket s4( std::move( s1 ) );
	s2 = std::move( s4 );

	[[maybe_unused]] mart::nw::socks::RaiiSocket& raw_socket = s2.as_raii_socket();

	CHECK_NOTHROW( s2.bind( e1 ) );
	// socket can't be rebinded to a different one
	CHECK_THROWS( s2.bind( e2 ) );
	CHECK_THROWS( s2.connect( e2 ) );
	CHECK( s2.get_local_endpoint() == e1 );
	CHECK( !s2.get_remote_endpoint().valid() );

	CHECK_THROWS( s2.send( mart::view_bytes( 5 ) ) );
}

TEST_CASE( "tcp_simple_exchange", "[net]" )
{
	using namespace mart::nw::ip;
	tcp::endpoint e1 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1584 } };
	tcp::endpoint e2 = { mart::nw::ip::address_local_host, mart::nw::ip::port_nr{ 1486 } };

	auto s1_future = std::async( std::launch::async, [&] {
		tcp::Acceptor ac( e1 );
		return ac.accept( std::chrono::milliseconds( 1000 ) );
	} );

	tcp::Socket s2;
	s2.bind( e2 );
	s2.connect( e1 );

	auto s1 = s1_future.get();
	CHECK( s1.is_valid() );

	CHECK( s2.get_remote_endpoint() == e1 );
	CHECK( s1.get_remote_endpoint() == e2 );

	const int data_orig = 0xffa1;
	int       data_rec{};
	s1.send( mart::view_bytes( data_orig ) );
	auto rec = s2.recv( mart::view_bytes_mutable( data_rec ) );

	CHECK( rec.size_inBytes() == sizeof( int ) );
	CHECK( data_orig == data_rec );

}<|endoftext|>


<commit_before>/*
 * Copyright (C) the FFLAS-FFPACK group
 * Written by Pascal Giorgi <pascal.giorgi@lirmm.fr>
 *
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */
#include <iomanip>
#include <iostream>
#include <random>

#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/test-utils.h"
#include "fflas-ffpack/utils/fflas_io.h"
#include "fflas-ffpack/utils/fflas_memory.h"

#include <givaro/modular.h>
#include <recint/rint.h>

#include "fflas-ffpack/fflas/fflas_transpose.h"

using namespace std;
using namespace FFLAS;
using namespace FFPACK;

using Givaro::Modular;
using Givaro::ModularBalanced;

/******************************************************************************/
template <typename Elt>
class Test {
    public:
        using Field = Modular<Elt>;
        using Elt_ptr = typename Field::Element_ptr;
        using Residu = typename Field::Residu_t;
        template <bool B, class T = void>
        using enable_if_t = typename std::enable_if<B, T>::type;
        template <typename Simd>
        using is_same_element = typename Simd::template is_same_element<Field>;
        template <typename E>
        using enable_if_no_simd_t = enable_if_t<Simd<E>::vect_size == 1>;
        template <typename E>
        using enable_if_simd128_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 16>;
        template <typename E>
        using enable_if_simd256_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 32>;
        template <typename E>
        using enable_if_simd512_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 64>;

        /* ctor */
        Test () : F(cardinality()) {
        }

        /* */
        template <typename _E = Elt,
                  enable_if_t<!is_same<_E, Givaro::Integer>::value>* = nullptr>
        static Residu
        cardinality () {
            return Field::maxCardinality();
        }

        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Givaro::Integer>::value>* = nullptr>
        static Residu
        cardinality () {
            /* Test Givaro::Integer with a large (=more than a word) modulus */
            return Givaro::Integer ("0x100000000000000000000000000000000");
        }

        /* main test function */
        template <typename Simd = NoSimd<Elt>,
                  enable_if_t<is_same_element<Simd>::value>* = nullptr>
        bool test_ftranspose (size_t m, size_t n, Elt_ptr A, size_t lda,
                                                    Elt_ptr B, size_t ldb) {
            Elt_ptr M, Mt;
            if (A == B) {
                M = fflas_new (F, ldb, lda);
                finit (F, ldb, lda, M, lda);
                fassign (F, m, n, A, lda, M, lda);
                Mt = M;
            }
            else {
                M = A;
                Mt = B;
            }
            ftranspose<Field, Simd> (F, m, n, M, lda, Mt, ldb);

            bool ok = true;
            for (size_t i = 0; i < m; i++)
                for (size_t j = 0; j < n; j++)
                    ok = ok && ((*(Mt+j*ldb+i)) == (*(A+i*lda+j)));

            if (!ok) {
                cerr << "Error, with " << m << "x" << n << " matrix"
                     << (lda == n ? "" : " with stride " + to_string(lda))
                     << (A == B ? " (inplace variant)" : "") << " over "
                     << F.type_string() << " using " << Simd::type_string()
                     << endl;
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < n; j++)
                        if ((*(Mt+j*ldb+i)) != (*(A+i*lda+j))) {
                            cerr << "   at index (" << j << ", " << i
                                 << ") expected " << *(A+i*lda+j) << " got "
                                 << *(Mt+j*ldb+i) << endl;
                        }
            }

            if (A == B) {
                fflas_delete (M);
            }
            return ok;
        }

        /* perform the tests for all sizes and types of matrices */
        template <typename Simd = NoSimd<Elt>,
                  enable_if_t<is_same_element<Simd>::value>* = nullptr>
        bool doTests () {
            bool ok = true;

            /* square matrices */
            size_t nrows[] = { 3*FFLAS_TRANSPOSE_BLOCKSIZE,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size+3 };
            for (auto m: nrows) {
                Elt_ptr M = fflas_new (F, m, m);
                Elt_ptr Mt = fflas_new (F, m, m);

                finit (F, m, m, M, m);
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < m; j++)
		      F.assign (M[i*m+j], (uint64_t)(i << 8) + j);
                finit (F, m, m, Mt, m);

                /* not inplace full matrix */
                ok &= test_ftranspose<Simd> (m, m, M, m, Mt, m);

                /* not inplace submatrix */
                size_t s = m - FFLAS_TRANSPOSE_BLOCKSIZE;
                ok &= test_ftranspose<Simd> (s, s, M, m, Mt, m);

                /* inplace full matrix */
                ok &= test_ftranspose<Simd> (m, m, M, m, M, m);

                /* inplace submatrix */
                s = m - Simd::vect_size;
                ok &= test_ftranspose<Simd> (s, s, M, m, M, m);

                fflas_delete (M);
                fflas_delete (Mt);
            }

            /* non square matrices */
            size_t ncols[] = { 2*FFLAS_TRANSPOSE_BLOCKSIZE,
                               4*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+2*Simd::vect_size+1};
            for (size_t i = 0; i < 3; i++) {
                size_t m = nrows[i];
                size_t n = ncols[i];

                Elt_ptr M = fflas_new (F, m, n);
                Elt_ptr Mt = fflas_new (F, n, m);

                finit (F, m, n, M, n);
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < n; j++)
		      F.assign (M[i*n+j], (uint64_t)(i << 8) + j);
                finit (F, n, m, Mt, m);

                /* not inplace full matrix */
                ok &= test_ftranspose<Simd> (m, n, M, n, Mt, m);

                /* not inplace submatrix */
                size_t s = m - Simd::vect_size;
                size_t t = n - 2*Simd::vect_size+1;
                ok &= test_ftranspose<Simd> (s, t, M, n, Mt, m);

                /* inplace full matrix */
                ok &= test_ftranspose<Simd> (m, n, M, n, M, m);

                fflas_delete (M);
                fflas_delete (Mt);
            }

            /* print results */
            std::cout << F.type_string()
                      << string (36-F.type_string().size(), '.') << " "
                      << Simd::type_string()
                      << string (36-Simd::type_string().size(), '.') << " "
                      << (ok ? "PASSED" : "FAILED")
                      << endl;

            return ok;
        }

        /* run tests: call doTests for all available Simd structs */
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_no_simd_t<_E>* = nullptr>
        bool run () {
            return doTests();
        }

#ifdef __FFLASFFPACK_HAVE_SSE4_1_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd128_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>();
        }
#endif

#ifdef __FFLASFFPACK_HAVE_AVX_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd256_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>()
                    & doTests<Simd256<Elt>>();
        }
#endif

#ifdef __FFLASFFPACK_HAVE_AVX512DQ_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd512_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>()
                    & doTests<Simd256<Elt>>() & doTests<Simd512<Elt>>();
        }
#endif

    protected:
        Field F;
};

/******************************************************************************/
int main(int argc, char** argv)
{
    std::cout << std::setprecision(17);
    std::cerr << std::setprecision(17);

    bool ok = true;

    ok &= Test<float>().run();
    ok &= Test<double>().run();
    ok &= Test<uint64_t>().run();
    ok &= Test<int64_t>().run();
    ok &= Test<uint32_t>().run();
    ok &= Test<int32_t>().run();
    ok &= Test<uint16_t>().run();
    ok &= Test<int16_t>().run();
    ok &= Test<Givaro::Integer>().run();
    ok &= Test<RecInt::rint<6>>().run();
    ok &= Test<RecInt::ruint<6>>().run();
    ok &= Test<RecInt::rint<7>>().run();
    ok &= Test<RecInt::ruint<7>>().run();
    ok &= Test<RecInt::rint<8>>().run();
    ok &= Test<RecInt::ruint<8>>().run();

    return !ok;
}
<commit_msg>Fix test-storage-transpose for simd512<commit_after>/*
 * Copyright (C) the FFLAS-FFPACK group
 * Written by Pascal Giorgi <pascal.giorgi@lirmm.fr>
 *
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */
#include <iomanip>
#include <iostream>
#include <random>

#include "fflas-ffpack/utils/args-parser.h"
#include "fflas-ffpack/utils/test-utils.h"
#include "fflas-ffpack/utils/fflas_io.h"
#include "fflas-ffpack/utils/fflas_memory.h"

#include <givaro/modular.h>
#include <recint/rint.h>

#include "fflas-ffpack/fflas/fflas_transpose.h"

using namespace std;
using namespace FFLAS;
using namespace FFPACK;

using Givaro::Modular;
using Givaro::ModularBalanced;

/******************************************************************************/
template <typename Elt>
class Test {
    public:
        using Field = Modular<Elt>;
        using Elt_ptr = typename Field::Element_ptr;
        using Residu = typename Field::Residu_t;
        template <bool B, class T = void>
        using enable_if_t = typename std::enable_if<B, T>::type;
        template <typename Simd>
        using is_same_element = typename Simd::template is_same_element<Field>;
        template <typename E>
        using enable_if_no_simd_t = enable_if_t<Simd<E>::vect_size == 1>;
        template <typename E>
        using enable_if_simd128_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 16>;
        template <typename E>
        using enable_if_simd256_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 32>;
        template <typename E>
        using enable_if_simd512_t = enable_if_t<sizeof(E)*Simd<E>::vect_size == 64>;

        /* ctor */
        Test () : F(cardinality()) {
        }

        /* */
        template <typename _E = Elt,
                  enable_if_t<!is_same<_E, Givaro::Integer>::value>* = nullptr>
        static Residu
        cardinality () {
            return Field::maxCardinality();
        }

        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Givaro::Integer>::value>* = nullptr>
        static Residu
        cardinality () {
            /* Test Givaro::Integer with a large (=more than a word) modulus */
            return Givaro::Integer ("0x100000000000000000000000000000000");
        }

        /* main test function */
        template <typename Simd = NoSimd<Elt>,
                  enable_if_t<is_same_element<Simd>::value>* = nullptr>
        bool test_ftranspose (size_t m, size_t n, Elt_ptr A, size_t lda,
                                                    Elt_ptr B, size_t ldb) {
            Elt_ptr M, Mt;
            if (A == B) {
                M = fflas_new (F, ldb, lda);
                finit (F, ldb, lda, M, lda);
                fassign (F, m, n, A, lda, M, lda);
                Mt = M;
            }
            else {
                M = A;
                Mt = B;
            }
            ftranspose<Field, Simd> (F, m, n, M, lda, Mt, ldb);

            bool ok = true;
            for (size_t i = 0; i < m; i++)
                for (size_t j = 0; j < n; j++)
                    ok = ok && ((*(Mt+j*ldb+i)) == (*(A+i*lda+j)));

            if (!ok) {
                cerr << "Error, with " << m << "x" << n << " matrix"
                     << (lda == n ? "" : " with stride " + to_string(lda))
                     << (A == B ? " (inplace variant)" : "") << " over "
                     << F.type_string() << " using " << Simd::type_string()
                     << endl;
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < n; j++)
                        if ((*(Mt+j*ldb+i)) != (*(A+i*lda+j))) {
                            cerr << "   at index (" << j << ", " << i
                                 << ") expected " << *(A+i*lda+j) << " got "
                                 << *(Mt+j*ldb+i) << endl;
                        }
            }

            if (A == B) {
                fflas_delete (M);
            }
            return ok;
        }

        /* perform the tests for all sizes and types of matrices */
        template <typename Simd = NoSimd<Elt>,
                  enable_if_t<is_same_element<Simd>::value>* = nullptr>
        bool doTests () {
            bool ok = true;

            /* square matrices */
            size_t nrows[] = { 3*FFLAS_TRANSPOSE_BLOCKSIZE,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size+3 };
            for (auto m: nrows) {
                Elt_ptr M = fflas_new (F, m, m);
                Elt_ptr Mt = fflas_new (F, m, m);

                finit (F, m, m, M, m);
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < m; j++)
		      F.assign (M[i*m+j], (uint64_t)(i << 8) + j);
                finit (F, m, m, Mt, m);

                /* not inplace full matrix */
                ok &= test_ftranspose<Simd> (m, m, M, m, Mt, m);

                /* not inplace submatrix */
                size_t s = m - FFLAS_TRANSPOSE_BLOCKSIZE;
                ok &= test_ftranspose<Simd> (s, s, M, m, Mt, m);

                /* inplace full matrix */
                ok &= test_ftranspose<Simd> (m, m, M, m, M, m);

                /* inplace submatrix */
                s = m - Simd::vect_size;
                ok &= test_ftranspose<Simd> (s, s, M, m, M, m);

                fflas_delete (M);
                fflas_delete (Mt);
            }

            /* non square matrices */
            size_t ncols[] = { 2*FFLAS_TRANSPOSE_BLOCKSIZE,
                               4*FFLAS_TRANSPOSE_BLOCKSIZE+Simd::vect_size,
                               3*FFLAS_TRANSPOSE_BLOCKSIZE+2*Simd::vect_size+1};
            for (size_t i = 0; i < 3; i++) {
                size_t m = nrows[i];
                size_t n = ncols[i];

                Elt_ptr M = fflas_new (F, m, n);
                Elt_ptr Mt = fflas_new (F, n, m);

                finit (F, m, n, M, n);
                for (size_t i = 0; i < m; i++)
                    for (size_t j = 0; j < n; j++)
		      F.assign (M[i*n+j], (uint64_t)(i << 8) + j);
                finit (F, n, m, Mt, m);

                /* not inplace full matrix */
                ok &= test_ftranspose<Simd> (m, n, M, n, Mt, m);

                /* not inplace submatrix */
                size_t s = m - Simd::vect_size;
                size_t t = n - 2*Simd::vect_size+1;
                ok &= test_ftranspose<Simd> (s, t, M, n, Mt, m);

                /* inplace full matrix */
                ok &= test_ftranspose<Simd> (m, n, M, n, M, m);

                fflas_delete (M);
                fflas_delete (Mt);
            }

            /* print results */
            std::cout << F.type_string()
                      << string (36-F.type_string().size(), '.') << " "
                      << Simd::type_string()
                      << string (36-Simd::type_string().size(), '.') << " "
                      << (ok ? "PASSED" : "FAILED")
                      << endl;

            return ok;
        }

        /* run tests: call doTests for all available Simd structs */
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_no_simd_t<_E>* = nullptr>
        bool run () {
            return doTests();
        }

#ifdef __FFLASFFPACK_HAVE_SSE4_1_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd128_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>();
        }
#endif

#ifdef __FFLASFFPACK_HAVE_AVX_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd256_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>()
                    & doTests<Simd256<Elt>>();
        }
#endif

#ifdef __FFLASFFPACK_HAVE_AVX512DQ_INSTRUCTIONS
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, Elt>::value>* = nullptr,
                  enable_if_t<Simd<_E>::vect_size != 1>* = nullptr,
                  enable_if_simd512_t<_E>* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>()
                    & doTests<Simd256<Elt>>() & doTests<Simd512<Elt>>();
        }

        /* Workaround for Simd512<(u)int32/16_t> which does not exist */
        template <typename _E = Elt,
                  enable_if_t<is_same<_E, uint32_t>::value
                              || is_same<_E, int32_t>::value
                              || is_same<_E, uint16_t>::value
                              || is_same<_E, int16_t>::value
                             >* = nullptr>
        bool run () {
            return doTests() & doTests<Simd128<Elt>>()
                    & doTests<Simd256<Elt>>();
        }
#endif

    protected:
        Field F;
};

/******************************************************************************/
int main(int argc, char** argv)
{
    std::cout << std::setprecision(17);
    std::cerr << std::setprecision(17);

    bool ok = true;

    ok &= Test<float>().run();
    ok &= Test<double>().run();
    ok &= Test<uint64_t>().run();
    ok &= Test<int64_t>().run();
    ok &= Test<uint32_t>().run();
    ok &= Test<int32_t>().run();
    ok &= Test<uint16_t>().run();
    ok &= Test<int16_t>().run();
    ok &= Test<Givaro::Integer>().run();
    ok &= Test<RecInt::rint<6>>().run();
    ok &= Test<RecInt::ruint<6>>().run();
    ok &= Test<RecInt::rint<7>>().run();
    ok &= Test<RecInt::ruint<7>>().run();
    ok &= Test<RecInt::rint<8>>().run();
    ok &= Test<RecInt::ruint<8>>().run();

    return !ok;
}
<|endoftext|>


<commit_before>#include <functional>
#include <future>
#include "kernel.h"
#include "raster.h"
#include "symboltable.h"
#include "ilwisoperation.h"
#include "blockiterator.h"
#include "gridinterpolator.h"
#include "aggregateraster.h"

using namespace Ilwis;
using namespace RasterOperations;

Ilwis::OperationImplementation *AggregateRaster::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new AggregateRaster(metaid, expr);
}

AggregateRaster::AggregateRaster()
{
}

AggregateRaster::AggregateRaster(quint64 metaid, const Ilwis::OperationExpression &expr) :
    OperationImplementation(metaid, expr),
    _method(NumericStatistics::pSUM)
{
}

bool AggregateRaster::execute(ExecutionContext *ctx, SymbolTable& symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx,symTable)) != sPREPARED)
            return false;

    IGridCoverage outputGC = _outputObj.get<GridCoverage>();

    BoxedAsyncFunc aggregateFun = [&](const Box3D<qint32>& box) -> bool {
        Size sz = outputGC->size();
        PixelIterator iterOut(outputGC, box);
        BlockIterator blockIter(_inputObj.get<GridCoverage>(),Size(_groupSize,_groupSize), Size(sz.xsize() * _groupSize, sz.ysize()*_groupSize));
        NumericStatistics stats;
        while(iterOut != iterOut.end()) {
            GridBlock& block = *blockIter;
            stats.calculate(block.begin(), block.end(), _method);
            double v = stats[_method];
           *iterOut = v;
            ++iterOut;
            if ( iterOut.ychanged()) {
                qDebug() << v;
            }
            ++blockIter;
        }
        return true;
    };
    ctx->_threaded = false;
    bool res = OperationHelperRaster::execute(ctx, aggregateFun, outputGC);

    if ( res && ctx != 0) {
        QVariant value;
        value.setValue<IGridCoverage>(outputGC);
        ctx->addOutput(symTable,value,outputGC->name(), itGRID, outputGC->resource() );
    }
    return res;
}

NumericStatistics::PropertySets AggregateRaster::toMethod(const QString& nm) {
    QString mname = nm.toLower();
    if ( mname == "avg")
        return NumericStatistics::pMEAN;
    else if ( mname == "min")
        return NumericStatistics::pMIN;
    else if ( mname == "max")
        return NumericStatistics::pMAX;
    else if ( mname == "med")
        return NumericStatistics::pMEDIAN;
    else if ( mname == "pred")
        return NumericStatistics::pPREDOMINANT;
    else if ( mname == "std")
        return NumericStatistics::pSTDEV;
    else if ( mname == "sum")
        return NumericStatistics::pSUM;

    return NumericStatistics::pLAST    ;
}

Ilwis::OperationImplementation::State AggregateRaster::prepare(ExecutionContext *, const SymbolTable & )
{
    QString gc = _expression.parm(0).value();
    QString outputName = _expression.parm(0,false).value();
    int copylist = itDOMAIN | itCOORDSYSTEM;

    if (!_inputObj.prepare(gc, itGRID)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,gc,"");
        return sPREPAREFAILED;
    }

    _method = toMethod(_expression.parm(1).value());
    if ( _method == NumericStatistics::pLAST) {
        ERROR2(ERR_ILLEGAL_VALUE_2, "parameter value", " aggregation method");
        return sPREPAREFAILED;
    }
    bool ok;
    _groupSize = _expression.parm(2).value().toInt(&ok);
    if ( !ok || _groupSize < 2) {
        ERROR2(ERR_ILLEGAL_VALUE_2, "aggregation group size", QString::number(_groupSize));
        return sPREPAREFAILED;
    }

    _grouped = _expression.parm(3).value() == "true";
    if ( !_grouped)
        copylist |= itGEOREF;

    _outputObj = OperationHelperRaster::initialize(_inputObj,itGRID, copylist);
    if ( !_outputObj.isValid()) {
        ERROR1(ERR_NO_INITIALIZED_1, "output gridcoverage");
        return sPREPAREFAILED;
    }
    QString outputBaseName = outputName;
    int index = 0;
    if ( (index = outputName.lastIndexOf(".")) != -1) {
        outputBaseName = outputName.left(index);
    }
    IGridCoverage inputGC = _inputObj.get<GridCoverage>();
    IGridCoverage outputGC = _outputObj.get<GridCoverage>();
    if ( outputName != sUNDEF)
        _outputObj->setName(outputName);

    Box3D<qint32> box(inputGC->georeference()->size());
    if ( _grouped) {
        int xs = box.xlength();
        int ys = box.ylength();
        int newxs = xs / _groupSize;
        int newys = ys / _groupSize;
        box = Box3D<qint32>(Size(newxs, newys));

    }
    if ( _expression.parameterCount() == 5 || _grouped) {
        Box2D<double> envlope = inputGC->envelope();
        Resource res(QUrl("ilwis://internal/georeference"),itGEOREF);
        res.addProperty("size", IVARIANT(box.size()));
        res.addProperty("envelope", IVARIANT(envlope));
        res.addProperty("coordinatesystem", IVARIANT(inputGC->coordinateSystem()));
        res.addProperty("name", outputBaseName);
        res.addProperty("centerofpixel",inputGC->georeference()->centerOfPixel());
        IGeoReference  grf;
        grf.prepare(res);
        outputGC->georeference(grf);
        outputGC->envelope(envlope);
    }

    return sPREPARED;
}

quint64 AggregateRaster::createMetadata()
{
    QString url = QString("ilwis://operations/aggregateraster");
    Resource res(QUrl(url), itOPERATIONMETADATA);
    res.addProperty("namespace","ilwis");
    res.addProperty("longname","aggregateraster raster coverage");
    res.addProperty("syntax","resample(inputgridcoverage,{Avg|Max|Med|Min|Prd|Std|Sum}, groupsize,changegeometry[,new georefname])");
    res.addProperty("inparameters","4|5");
    res.addProperty("pin_1_type", itGRID);
    res.addProperty("pin_1_name", TR("input gridcoverage"));
    res.addProperty("pin_1_desc",TR("input gridcoverage with domain any domain"));
    res.addProperty("pin_2_type", itSTRING);
    res.addProperty("pin_2_name", TR("Aggregation Method"));
    res.addProperty("pin_2_desc",TR("the method how pixels inside a group will be accumulated"));
    res.addProperty("pin_3_type", itINTEGER);
    res.addProperty("pin_3_name", TR("Groupsize"));
    res.addProperty("pin_3_desc",TR("The size of the block used to aggregate"));
    res.addProperty("pin_4_type", itBOOL);
    res.addProperty("pin_4_name", TR("change geometry"));
    res.addProperty("pin_4_desc",TR("The aggregation can either create a map with a reduced size proportional to de block size or use the same geometry size but fill all pixels in the block with the aggregate"));
    res.addProperty("pin_5_type", itSTRING);
    res.addProperty("pin_5_name", TR("georeference name"));
    res.addProperty("pin_5_desc",TR("optional parameter indicating a name for the new geometry, else the name will come from the output grid"));
    res.addProperty("outparameters",1);
    res.addProperty("pout_1_type", itGRID);
    res.addProperty("pout_1_name", TR("output gridcoverage"));
    res.addProperty("pout_1_desc",TR("output gridcoverage with the domain of the input map"));
    res.prepare();
    url += "=" + QString::number(res.id());
    res.setUrl(url);

    mastercatalog()->addItems({res});
    return res.id();
}

<commit_msg>correct shifting bounding box for multicore variant of this operation<commit_after>#include <functional>
#include <future>
#include "kernel.h"
#include "raster.h"
#include "symboltable.h"
#include "ilwisoperation.h"
#include "blockiterator.h"
#include "gridinterpolator.h"
#include "aggregateraster.h"

using namespace Ilwis;
using namespace RasterOperations;

Ilwis::OperationImplementation *AggregateRaster::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new AggregateRaster(metaid, expr);
}

AggregateRaster::AggregateRaster()
{
}

AggregateRaster::AggregateRaster(quint64 metaid, const Ilwis::OperationExpression &expr) :
    OperationImplementation(metaid, expr),
    _method(NumericStatistics::pSUM)
{
}

bool AggregateRaster::execute(ExecutionContext *ctx, SymbolTable& symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx,symTable)) != sPREPARED)
            return false;

    IGridCoverage outputGC = _outputObj.get<GridCoverage>();

    BoxedAsyncFunc aggregateFun = [&](const Box3D<qint32>& box) -> bool {
        //Size sz = outputGC->size();
        PixelIterator iterOut(outputGC, box);
        Box3D<qint32> inpBox(Point3D<qint32>(box.min_corner().x(), box.min_corner().y() * _groupSize),
                             Point3D<qint32>((box.max_corner().x()+1) * _groupSize - 1, (box.max_corner().y() + 1) * _groupSize - 1));

        //BlockIterator blockIter(_inputObj.get<GridCoverage>(),Size(_groupSize,_groupSize), Size(sz.xsize() * _groupSize, sz.ysize()*_groupSize));
        //Box3D<qint32> sz2(Size(sz.xsize() * _groupSize, sz.ysize()*_groupSize));
        BlockIterator blockIter(_inputObj.get<GridCoverage>(),Size(_groupSize,_groupSize), inpBox);
        NumericStatistics stats;
        while(iterOut != iterOut.end()) {
            GridBlock& block = *blockIter;
            stats.calculate(block.begin(), block.end(), _method);
            double v = stats[_method];
           *iterOut = v;
            ++iterOut;
            ++blockIter;
        }
        return true;
    };
    //ctx->_threaded = false;
    bool res = OperationHelperRaster::execute(ctx, aggregateFun, outputGC);

    if ( res && ctx != 0) {
        QVariant value;
        value.setValue<IGridCoverage>(outputGC);
        ctx->addOutput(symTable,value,outputGC->name(), itGRID, outputGC->resource() );
    }
    return res;
}

NumericStatistics::PropertySets AggregateRaster::toMethod(const QString& nm) {
    QString mname = nm.toLower();
    if ( mname == "avg")
        return NumericStatistics::pMEAN;
    else if ( mname == "min")
        return NumericStatistics::pMIN;
    else if ( mname == "max")
        return NumericStatistics::pMAX;
    else if ( mname == "med")
        return NumericStatistics::pMEDIAN;
    else if ( mname == "pred")
        return NumericStatistics::pPREDOMINANT;
    else if ( mname == "std")
        return NumericStatistics::pSTDEV;
    else if ( mname == "sum")
        return NumericStatistics::pSUM;

    return NumericStatistics::pLAST    ;
}

Ilwis::OperationImplementation::State AggregateRaster::prepare(ExecutionContext *, const SymbolTable & )
{
    QString gc = _expression.parm(0).value();
    QString outputName = _expression.parm(0,false).value();
    int copylist = itDOMAIN | itCOORDSYSTEM;

    if (!_inputObj.prepare(gc, itGRID)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,gc,"");
        return sPREPAREFAILED;
    }

    _method = toMethod(_expression.parm(1).value());
    if ( _method == NumericStatistics::pLAST) {
        ERROR2(ERR_ILLEGAL_VALUE_2, "parameter value", " aggregation method");
        return sPREPAREFAILED;
    }
    bool ok;
    _groupSize = _expression.parm(2).value().toInt(&ok);
    if ( !ok || _groupSize < 2) {
        ERROR2(ERR_ILLEGAL_VALUE_2, "aggregation group size", QString::number(_groupSize));
        return sPREPAREFAILED;
    }

    _grouped = _expression.parm(3).value() == "true";
    if ( !_grouped)
        copylist |= itGEOREF;

    _outputObj = OperationHelperRaster::initialize(_inputObj,itGRID, copylist);
    if ( !_outputObj.isValid()) {
        ERROR1(ERR_NO_INITIALIZED_1, "output gridcoverage");
        return sPREPAREFAILED;
    }
    QString outputBaseName = outputName;
    int index = 0;
    if ( (index = outputName.lastIndexOf(".")) != -1) {
        outputBaseName = outputName.left(index);
    }
    IGridCoverage inputGC = _inputObj.get<GridCoverage>();
    IGridCoverage outputGC = _outputObj.get<GridCoverage>();
    if ( outputName != sUNDEF)
        _outputObj->setName(outputName);

    Box3D<qint32> box(inputGC->georeference()->size());
    if ( _grouped) {
        int xs = box.xlength();
        int ys = box.ylength();
        int newxs = xs / _groupSize;
        int newys = ys / _groupSize;
        box = Box3D<qint32>(Size(newxs, newys));

    }
    if ( _expression.parameterCount() == 5 || _grouped) {
        Box2D<double> envlope = inputGC->envelope();
        Resource res(QUrl("ilwis://internal/georeference"),itGEOREF);
        res.addProperty("size", IVARIANT(box.size()));
        res.addProperty("envelope", IVARIANT(envlope));
        res.addProperty("coordinatesystem", IVARIANT(inputGC->coordinateSystem()));
        res.addProperty("name", outputBaseName);
        res.addProperty("centerofpixel",inputGC->georeference()->centerOfPixel());
        IGeoReference  grf;
        grf.prepare(res);
        outputGC->georeference(grf);
        outputGC->envelope(envlope);
    }

    return sPREPARED;
}

quint64 AggregateRaster::createMetadata()
{
    QString url = QString("ilwis://operations/aggregateraster");
    Resource res(QUrl(url), itOPERATIONMETADATA);
    res.addProperty("namespace","ilwis");
    res.addProperty("longname","aggregateraster raster coverage");
    res.addProperty("syntax","resample(inputgridcoverage,{Avg|Max|Med|Min|Prd|Std|Sum}, groupsize,changegeometry[,new georefname])");
    res.addProperty("inparameters","4|5");
    res.addProperty("pin_1_type", itGRID);
    res.addProperty("pin_1_name", TR("input gridcoverage"));
    res.addProperty("pin_1_desc",TR("input gridcoverage with domain any domain"));
    res.addProperty("pin_2_type", itSTRING);
    res.addProperty("pin_2_name", TR("Aggregation Method"));
    res.addProperty("pin_2_desc",TR("the method how pixels inside a group will be accumulated"));
    res.addProperty("pin_3_type", itINTEGER);
    res.addProperty("pin_3_name", TR("Groupsize"));
    res.addProperty("pin_3_desc",TR("The size of the block used to aggregate"));
    res.addProperty("pin_4_type", itBOOL);
    res.addProperty("pin_4_name", TR("change geometry"));
    res.addProperty("pin_4_desc",TR("The aggregation can either create a map with a reduced size proportional to de block size or use the same geometry size but fill all pixels in the block with the aggregate"));
    res.addProperty("pin_5_type", itSTRING);
    res.addProperty("pin_5_name", TR("georeference name"));
    res.addProperty("pin_5_desc",TR("optional parameter indicating a name for the new geometry, else the name will come from the output grid"));
    res.addProperty("outparameters",1);
    res.addProperty("pout_1_type", itGRID);
    res.addProperty("pout_1_name", TR("output gridcoverage"));
    res.addProperty("pout_1_desc",TR("output gridcoverage with the domain of the input map"));
    res.prepare();
    url += "=" + QString::number(res.id());
    res.setUrl(url);

    mastercatalog()->addItems({res});
    return res.id();
}

<|endoftext|>


<commit_before>/*
    MIT License

    Copyright (c) 2017-2018, Alexey Dynda

    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 "ssd1306_spi_hw.h"
#include "ssd1306_spi.h"

#include "intf/ssd1306_interface.h"
#include "lcd/lcd_common.h"
#include "hal/io.h"

#include <stdlib.h>

#ifdef SSD1306_SPI_SUPPORTED
/* STANDARD branch */
    #include <SPI.h>

void ssd1306_spiConfigure_hw()
{
    SPI.begin();
}

static void ssd1306_spiClose_hw()
{
}

static void ssd1306_spiStart_hw()
{
    SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
    if (s_ssd1306_cs >= 0)
    {
        digitalWrite(s_ssd1306_cs,LOW);
    }
}

static void ssd1306_spiStop_hw()
{
    if (s_ssd1306_cs >= 0)
    {
        digitalWrite(s_ssd1306_cs, HIGH);
    }
    if (g_lcd_type == LCD_TYPE_PCD8544)
    {
        digitalWrite(s_ssd1306_dc, LOW);
        SPI.transfer( 0x00 ); // Send NOP command to allow last data byte to pass (bug in PCD8544?)
                              // ssd1306 E3h is NOP command
    }
    SPI.endTransaction();
}

static void ssd1306_spiSendByte_hw(uint8_t data)
{
    SPI.transfer(data);
}

void ssd1306_spiInit_hw(int8_t cesPin, int8_t dcPin)
{
    if (cesPin >=0) pinMode(cesPin, OUTPUT);
    if (dcPin >= 0) pinMode(dcPin, OUTPUT);
    if (cesPin) s_ssd1306_cs = cesPin;
    if (dcPin) s_ssd1306_dc = dcPin;
    ssd1306_startTransmission = ssd1306_spiStart_hw;
    ssd1306_endTransmission = ssd1306_spiStop_hw;
    ssd1306_sendByte = ssd1306_spiSendByte_hw;
    ssd1306_closeInterface = ssd1306_spiClose_hw;
    ssd1306_commandStart = ssd1306_spiCommandStart;
    ssd1306_dataStart = ssd1306_spiDataStart;
}

#endif

<commit_msg>SPI speed increase<commit_after>/*
    MIT License

    Copyright (c) 2017-2018, Alexey Dynda

    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 "ssd1306_spi_hw.h"
#include "ssd1306_spi.h"

#include "intf/ssd1306_interface.h"
#include "lcd/lcd_common.h"
#include "hal/io.h"

#include <stdlib.h>

#ifdef SSD1306_SPI_SUPPORTED
/* STANDARD branch */
    #include <SPI.h>

void ssd1306_spiConfigure_hw()
{
    SPI.begin();
}

static void ssd1306_spiClose_hw()
{
}

static void ssd1306_spiStart_hw()
{
    /* anyway, oled ssd1331 cannot work faster, clock cycle should be > 150ns: *
     * 1s / 150ns ~ 6.7MHz                                                     */
    SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
    if (s_ssd1306_cs >= 0)
    {
        digitalWrite(s_ssd1306_cs,LOW);
    }
}

static void ssd1306_spiStop_hw()
{
    if (s_ssd1306_cs >= 0)
    {
        digitalWrite(s_ssd1306_cs, HIGH);
    }
    if (g_lcd_type == LCD_TYPE_PCD8544)
    {
        digitalWrite(s_ssd1306_dc, LOW);
        SPI.transfer( 0x00 ); // Send NOP command to allow last data byte to pass (bug in PCD8544?)
                              // ssd1306 E3h is NOP command
    }
    SPI.endTransaction();
}

static void ssd1306_spiSendByte_hw(uint8_t data)
{
    SPI.transfer(data);
}

void ssd1306_spiInit_hw(int8_t cesPin, int8_t dcPin)
{
    if (cesPin >=0) pinMode(cesPin, OUTPUT);
    if (dcPin >= 0) pinMode(dcPin, OUTPUT);
    if (cesPin) s_ssd1306_cs = cesPin;
    if (dcPin) s_ssd1306_dc = dcPin;
    ssd1306_startTransmission = ssd1306_spiStart_hw;
    ssd1306_endTransmission = ssd1306_spiStop_hw;
    ssd1306_sendByte = ssd1306_spiSendByte_hw;
    ssd1306_closeInterface = ssd1306_spiClose_hw;
    ssd1306_commandStart = ssd1306_spiCommandStart;
    ssd1306_dataStart = ssd1306_spiDataStart;
}

#endif

<|endoftext|>


<commit_before>/**
  * Touhou Community Reliant Automatic Patcher
  * Main DLL
  *
  * ----
  *
  * Persistent string storage, and translation of hardcoded strings.
  */

#include "thcrap.h"
#include <unordered_map>

/// Detour chains
/// -------------
W32U8_DETOUR_CHAIN_DEF(MessageBox);
W32U8_DETOUR_CHAIN_DEF(FindFirstFile);
/// -------------

// Since we can't use the jsondata module to make this repatchable,
// we only need to keep the last parsed JSON object around to
// provide the "backing memory" for the ID strings.
json_t *backing_obj = nullptr;

// Length-prefixed string object used for persistent storage
typedef struct {
	size_t len;
	char str;
} storage_string_t;

std::unordered_map<size_t, storage_string_t *> strings_storage;

SRWLOCK stringlocs_srwlock = {SRWLOCK_INIT};
std::unordered_map<const char *, const char *> stringlocs;

#define addr_key_len 2 + (sizeof(void*) * 2) + 1

void stringlocs_reparse(void)
{
	json_t* new_obj = stack_game_json_resolve("stringlocs.js", NULL);
	const char *key;
	const json_t *val;

	AcquireSRWLockExclusive(&stringlocs_srwlock);
	stringlocs.clear();

	json_object_foreach(new_obj, key, val) {
		// TODO: For now, we're nagging developers with one message box for
		// every single parse error. It'd certainly be better if we gathered
		// all errors into a single message box to be printed at the end of
		// the parsing, and even had a somewhat generic solution if we do
		// more of these conversions.
#define stringlocs_log_error(msg) \
	log_mboxf(NULL, MB_OK | MB_ICONEXCLAMATION, \
		"Error parsing stringlocs.js: \"%s\" " msg".", key, sizeof(size_t) * 8 \
	)

		if(!json_is_string(val)) {
			stringlocs_log_error("must be a JSON string");
			continue;
		}
		str_address_ret_t addr_ret;
		auto *addr = (const char *)str_address_value(key, NULL, &addr_ret);
		if(addr_ret.error == STR_ADDRESS_ERROR_NONE) {
			stringlocs[addr] = json_string_value(val);
		}
		if(addr_ret.error & STR_ADDRESS_ERROR_OVERFLOW) {
			stringlocs_log_error("exceeds %d bits");
		}
		if(addr_ret.error & STR_ADDRESS_ERROR_GARBAGE) {
			stringlocs_log_error("has garbage at the end");
		}
#undef stringlocs_log_error
	}

	json_decref(backing_obj);
	backing_obj = new_obj;

	ReleaseSRWLockExclusive(&stringlocs_srwlock);
}

const char* strings_id(const char *str)
{
	const char *ret = nullptr;
	AcquireSRWLockShared(&stringlocs_srwlock);
	auto id_key = stringlocs.find(str);
	if(id_key != stringlocs.end()) {
		ret = id_key->second;
	}
	ReleaseSRWLockShared(&stringlocs_srwlock);
	return ret;
}

const json_t* strings_get(const char *id)
{
	return json_object_get(jsondata_get("stringdefs.js"), id);
}

stringref_t strings_get_fallback(const string_named_t& sn)
{
	auto ret = strings_get(sn.id);
	if(!json_is_string(ret)) {
		return sn.fallback;
	}
	return ret;
}

const char* strings_lookup(const char *in, size_t *out_len)
{
	const char *ret = in;

	if(!in) {
		return in;
	}

	AcquireSRWLockShared(&stringlocs_srwlock);
	auto id = strings_id(in);
	if(id) {
		auto *new_str = json_string_value(strings_get(id));
		if(new_str && new_str[0]) {
			ret = new_str;
		}
	}
	ReleaseSRWLockShared(&stringlocs_srwlock);

	if(out_len) {
		*out_len = strlen(ret);
	}
	return ret;
}

void strings_va_lookup(va_list va, const char *format)
{
	const char *p = format;
	while(*p) {
		printf_format_t fmt;
		int i;

		// Skip characters before '%'
		for(; *p && *p != '%'; p++);
		if(!*p) {
			break;
		}
		// *p == '%' here
		p++;

		// output a single '%' character
		if(*p == '%') {
			p++;
			continue;
		}
		p = printf_format_parse(&fmt, p);
		for(i = 0; i < fmt.argc_before_type; i++) {
			va_arg(va, int);
		}
		if(fmt.type == 's' || fmt.type == 'S') {
			*(const char**)va = strings_lookup(*(const char**)va, NULL);
		}
		for(i = 0; i < fmt.type_size_in_ints; i++) {
			va_arg(va, int);
		}
	}
}

char* strings_storage_get(const size_t slot, size_t min_len)
{
	auto stored = strings_storage.find(slot);
	auto *ret = stored != strings_storage.end() ? stored->second : nullptr;

	// MSVCRT's realloc implementation moves the buffer every time, even if the
	// new length is shorter...
	if(ret == nullptr || (min_len && ret->len < min_len)) {
		auto *ret_new = (storage_string_t*)realloc(ret, min_len + sizeof(storage_string_t));
		// Yes, this correctly handles a realloc failure.
		if(ret_new) {
			ret_new->len = min_len;
			if(!ret) {
				ret_new->str = 0;
			}
			strings_storage[slot] = ret_new;
			ret = ret_new;
		}
	}
	if(ret) {
		return &ret->str;
	}
	return nullptr;
}

const char* strings_vsprintf(const size_t slot, const char *format, va_list va)
{
	char *ret = NULL;
	size_t str_len;

	format = strings_lookup(format, NULL);
	strings_va_lookup(va, format);

	if(!format) {
		return NULL;
	}
	str_len = _vscprintf(format, va) + 1;

	ret = strings_storage_get(slot, str_len);
	if(ret) {
		vsprintf(ret, format, va);
		return ret;
	}
	// Try to save the situation at least somewhat...
	return format;
}

const char* strings_vsprintf_msvcrt14(const char *format, const size_t slot, va_list va)
{
	return strings_vsprintf(slot, format, va);
}

const char* strings_sprintf(const size_t slot, const char *format, ...)
{
	va_list va;
	const char *ret;
	va_start(va, format);
	ret = strings_vsprintf(slot, format, va);
	return ret;
}

const char* strings_strclr(const size_t slot)
{
	char *ret = strings_storage_get(slot, 0);
	if(ret) {
		ret[0] = 0;
	}
	return ret;
}

const char* strings_strcat(const size_t slot, const char *src)
{
	char *ret = strings_storage_get(slot, 0);
	size_t ret_len = strlen(ret);
	size_t src_len;

	src = strings_lookup(src, &src_len);

	ret = strings_storage_get(slot, ret_len + src_len + 1);
	if(ret) {
		strncpy(ret + ret_len, src, src_len + 1);
		return ret;
	}
	// Try to save the situation at least somewhat...
	return src;
}

const char* strings_replace(const size_t slot, const char *src, const char *dst)
{
	char *ret = strings_storage_get(slot, 0);
	dst = dst ? dst : "";
	if(src && ret) {
		size_t src_len = strlen(src);
		size_t dst_len = strlen(dst);
		while(ret) {
			char *src_pos = NULL;
			char *copy_pos = NULL;
			char *rest_pos = NULL;
			size_t ret_len = strlen(ret);
			// We do this first since the string address might change after
			// reallocation, thus invalidating the strstr() result
			ret = strings_storage_get(slot, ret_len + dst_len);
			if(!ret) {
				break;
			}
			src_pos = strstr(ret, src);
			if(!src_pos) {
				break;
			}
			copy_pos = src_pos + dst_len;
			rest_pos = src_pos + src_len;
			memmove(copy_pos, rest_pos, strlen(rest_pos) + 1);
			memcpy(src_pos, dst, dst_len);
		}
	}
	// Try to save the situation at least somewhat...
	return ret ? ret : dst;
}

/// String lookup hooks
/// -------------------
int WINAPI strings_MessageBoxA(
	HWND hWnd,
	LPCSTR lpText,
	LPCSTR lpCaption,
	UINT uType
)
{
	lpText = strings_lookup(lpText, NULL);
	lpCaption = strings_lookup(lpCaption, NULL);
	return chain_MessageBoxU(hWnd, lpText, lpCaption, uType);
}

HANDLE WINAPI strings_FindFirstFileA(
	LPCSTR lpFileName,
	LPWIN32_FIND_DATAA lpFindFileData
)
{
	return chain_FindFirstFileU(strings_lookup(lpFileName, NULL), lpFindFileData);
}
/// -------------------

void strings_mod_init(void)
{
	jsondata_add("stringdefs.js");
	stringlocs_reparse();
}

void strings_mod_detour(void)
{
	detour_chain("user32.dll", 1,
		"MessageBoxA", strings_MessageBoxA, &chain_MessageBoxU,
		NULL
	);
	detour_chain("kernel32.dll", 1,
		"FindFirstFileA", strings_FindFirstFileA, &chain_FindFirstFileU,
		NULL
	);
}

void strings_mod_repatch(json_t *files_changed)
{
	const char *key;
	const json_t *val;
	json_object_foreach(files_changed, key, val) {
		if(strstr(key, "/stringlocs.")) {
			stringlocs_reparse();
		}
	}
}

void strings_mod_exit(void)
{
	for(auto& i : strings_storage) {
		SAFE_FREE(i.second);
	}
	strings_storage.clear();
	stringlocs.clear();
	backing_obj = json_decref_safe(backing_obj);
}
<commit_msg>Allow changing hardcoded stings for CreateFileA calls<commit_after>/**
  * Touhou Community Reliant Automatic Patcher
  * Main DLL
  *
  * ----
  *
  * Persistent string storage, and translation of hardcoded strings.
  */

#include "thcrap.h"
#include <unordered_map>

/// Detour chains
/// -------------
W32U8_DETOUR_CHAIN_DEF(MessageBox);
W32U8_DETOUR_CHAIN_DEF(FindFirstFile);
W32U8_DETOUR_CHAIN_DEF(CreateFile);

/// -------------

// Since we can't use the jsondata module to make this repatchable,
// we only need to keep the last parsed JSON object around to
// provide the "backing memory" for the ID strings.
json_t *backing_obj = nullptr;

// Length-prefixed string object used for persistent storage
typedef struct {
	size_t len;
	char str;
} storage_string_t;

std::unordered_map<size_t, storage_string_t *> strings_storage;

SRWLOCK stringlocs_srwlock = {SRWLOCK_INIT};
std::unordered_map<const char *, const char *> stringlocs;

#define addr_key_len 2 + (sizeof(void*) * 2) + 1

void stringlocs_reparse(void)
{
	json_t* new_obj = stack_game_json_resolve("stringlocs.js", NULL);
	const char *key;
	const json_t *val;

	AcquireSRWLockExclusive(&stringlocs_srwlock);
	stringlocs.clear();

	json_object_foreach(new_obj, key, val) {
		// TODO: For now, we're nagging developers with one message box for
		// every single parse error. It'd certainly be better if we gathered
		// all errors into a single message box to be printed at the end of
		// the parsing, and even had a somewhat generic solution if we do
		// more of these conversions.
#define stringlocs_log_error(msg) \
	log_mboxf(NULL, MB_OK | MB_ICONEXCLAMATION, \
		"Error parsing stringlocs.js: \"%s\" " msg".", key, sizeof(size_t) * 8 \
	)

		if(!json_is_string(val)) {
			stringlocs_log_error("must be a JSON string");
			continue;
		}
		str_address_ret_t addr_ret;
		auto *addr = (const char *)str_address_value(key, NULL, &addr_ret);
		if(addr_ret.error == STR_ADDRESS_ERROR_NONE) {
			stringlocs[addr] = json_string_value(val);
		}
		if(addr_ret.error & STR_ADDRESS_ERROR_OVERFLOW) {
			stringlocs_log_error("exceeds %d bits");
		}
		if(addr_ret.error & STR_ADDRESS_ERROR_GARBAGE) {
			stringlocs_log_error("has garbage at the end");
		}
#undef stringlocs_log_error
	}

	json_decref(backing_obj);
	backing_obj = new_obj;

	ReleaseSRWLockExclusive(&stringlocs_srwlock);
}

const char* strings_id(const char *str)
{
	const char *ret = nullptr;
	AcquireSRWLockShared(&stringlocs_srwlock);
	auto id_key = stringlocs.find(str);
	if(id_key != stringlocs.end()) {
		ret = id_key->second;
	}
	ReleaseSRWLockShared(&stringlocs_srwlock);
	return ret;
}

const json_t* strings_get(const char *id)
{
	return json_object_get(jsondata_get("stringdefs.js"), id);
}

stringref_t strings_get_fallback(const string_named_t& sn)
{
	auto ret = strings_get(sn.id);
	if(!json_is_string(ret)) {
		return sn.fallback;
	}
	return ret;
}

const char* strings_lookup(const char *in, size_t *out_len)
{
	const char *ret = in;

	if(!in) {
		return in;
	}

	AcquireSRWLockShared(&stringlocs_srwlock);
	auto id = strings_id(in);
	if(id) {
		auto *new_str = json_string_value(strings_get(id));
		if(new_str && new_str[0]) {
			ret = new_str;
		}
	}
	ReleaseSRWLockShared(&stringlocs_srwlock);

	if(out_len) {
		*out_len = strlen(ret);
	}
	return ret;
}

void strings_va_lookup(va_list va, const char *format)
{
	const char *p = format;
	while(*p) {
		printf_format_t fmt;
		int i;

		// Skip characters before '%'
		for(; *p && *p != '%'; p++);
		if(!*p) {
			break;
		}
		// *p == '%' here
		p++;

		// output a single '%' character
		if(*p == '%') {
			p++;
			continue;
		}
		p = printf_format_parse(&fmt, p);
		for(i = 0; i < fmt.argc_before_type; i++) {
			va_arg(va, int);
		}
		if(fmt.type == 's' || fmt.type == 'S') {
			*(const char**)va = strings_lookup(*(const char**)va, NULL);
		}
		for(i = 0; i < fmt.type_size_in_ints; i++) {
			va_arg(va, int);
		}
	}
}

char* strings_storage_get(const size_t slot, size_t min_len)
{
	auto stored = strings_storage.find(slot);
	auto *ret = stored != strings_storage.end() ? stored->second : nullptr;

	// MSVCRT's realloc implementation moves the buffer every time, even if the
	// new length is shorter...
	if(ret == nullptr || (min_len && ret->len < min_len)) {
		auto *ret_new = (storage_string_t*)realloc(ret, min_len + sizeof(storage_string_t));
		// Yes, this correctly handles a realloc failure.
		if(ret_new) {
			ret_new->len = min_len;
			if(!ret) {
				ret_new->str = 0;
			}
			strings_storage[slot] = ret_new;
			ret = ret_new;
		}
	}
	if(ret) {
		return &ret->str;
	}
	return nullptr;
}

const char* strings_vsprintf(const size_t slot, const char *format, va_list va)
{
	char *ret = NULL;
	size_t str_len;

	format = strings_lookup(format, NULL);
	strings_va_lookup(va, format);

	if(!format) {
		return NULL;
	}
	str_len = _vscprintf(format, va) + 1;

	ret = strings_storage_get(slot, str_len);
	if(ret) {
		vsprintf(ret, format, va);
		return ret;
	}
	// Try to save the situation at least somewhat...
	return format;
}

const char* strings_vsprintf_msvcrt14(const char *format, const size_t slot, va_list va)
{
	return strings_vsprintf(slot, format, va);
}

const char* strings_sprintf(const size_t slot, const char *format, ...)
{
	va_list va;
	const char *ret;
	va_start(va, format);
	ret = strings_vsprintf(slot, format, va);
	return ret;
}

const char* strings_strclr(const size_t slot)
{
	char *ret = strings_storage_get(slot, 0);
	if(ret) {
		ret[0] = 0;
	}
	return ret;
}

const char* strings_strcat(const size_t slot, const char *src)
{
	char *ret = strings_storage_get(slot, 0);
	size_t ret_len = strlen(ret);
	size_t src_len;

	src = strings_lookup(src, &src_len);

	ret = strings_storage_get(slot, ret_len + src_len + 1);
	if(ret) {
		strncpy(ret + ret_len, src, src_len + 1);
		return ret;
	}
	// Try to save the situation at least somewhat...
	return src;
}

const char* strings_replace(const size_t slot, const char *src, const char *dst)
{
	char *ret = strings_storage_get(slot, 0);
	dst = dst ? dst : "";
	if(src && ret) {
		size_t src_len = strlen(src);
		size_t dst_len = strlen(dst);
		while(ret) {
			char *src_pos = NULL;
			char *copy_pos = NULL;
			char *rest_pos = NULL;
			size_t ret_len = strlen(ret);
			// We do this first since the string address might change after
			// reallocation, thus invalidating the strstr() result
			ret = strings_storage_get(slot, ret_len + dst_len);
			if(!ret) {
				break;
			}
			src_pos = strstr(ret, src);
			if(!src_pos) {
				break;
			}
			copy_pos = src_pos + dst_len;
			rest_pos = src_pos + src_len;
			memmove(copy_pos, rest_pos, strlen(rest_pos) + 1);
			memcpy(src_pos, dst, dst_len);
		}
	}
	// Try to save the situation at least somewhat...
	return ret ? ret : dst;
}

/// String lookup hooks
/// -------------------
int WINAPI strings_MessageBoxA(
	HWND hWnd,
	LPCSTR lpText,
	LPCSTR lpCaption,
	UINT uType
)
{
	lpText = strings_lookup(lpText, NULL);
	lpCaption = strings_lookup(lpCaption, NULL);
	return chain_MessageBoxU(hWnd, lpText, lpCaption, uType);
}

HANDLE WINAPI strings_FindFirstFileA(
	LPCSTR lpFileName,
	LPWIN32_FIND_DATAA lpFindFileData
)
{
	return chain_FindFirstFileU(strings_lookup(lpFileName, NULL), lpFindFileData);
}

HANDLE WINAPI strings_CreateFileA(
	LPCSTR                lpFileName,
	DWORD                 dwDesiredAccess,
	DWORD                 dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD                 dwCreationDisposition,
	DWORD                 dwFlagsAndAttributes,
	HANDLE                hTemplateFile
)
{
	return chain_CreateFileU(
		strings_lookup(lpFileName, NULL),
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
	);
}
/// -------------------

void strings_mod_init(void)
{
	jsondata_add("stringdefs.js");
	stringlocs_reparse();
}

void strings_mod_detour(void)
{
	detour_chain("user32.dll", 1,
		"MessageBoxA", strings_MessageBoxA, &chain_MessageBoxU,
		NULL
	);
	detour_chain("kernel32.dll", 2,
		"FindFirstFileA", strings_FindFirstFileA, &chain_FindFirstFileU,
		"CreateFileA", strings_CreateFileA, &chain_CreateFileU,
		NULL
	);
}

void strings_mod_repatch(json_t *files_changed)
{
	const char *key;
	const json_t *val;
	json_object_foreach(files_changed, key, val) {
		if(strstr(key, "/stringlocs.")) {
			stringlocs_reparse();
		}
	}
}

void strings_mod_exit(void)
{
	for(auto& i : strings_storage) {
		SAFE_FREE(i.second);
	}
	strings_storage.clear();
	stringlocs.clear();
	backing_obj = json_decref_safe(backing_obj);
}
<|endoftext|>


<commit_before>#ifndef VG_GFF_READER_HPP_INCLUDED
#define VG_GFF_READER_HPP_INCLUDED

#include <iostream>
#include <sstream>
#include <string>
#include <map>

namespace vg {

    using namespace std;

    /**
     * A package of the information contained in a GFF3 record. The null "." entries in a
     * a GFF are parsed into empty strings or the default values of the numerical fields
     * as given below.
     */
    struct GFFRecord {
    public:
        GFFRecord() = default;
        ~GFFRecord() = default;

        string sequence_id;
        string source;
        string type;
        // 0-based indexing, unlike the actual GFF standard
        int64_t start = -1;
        // 0-based, inclusive
        int64_t end = -1;
        double score = numeric_limits<double>::quiet_NaN();
        bool strand_is_rev = false;
        int32_t phase = -1;
        string attributes;

        map<string, string> parse_attributes();
    };

    /**
     * A class that can parse and iterate over a GFF3 file.
     */
    class GFFReader {
    public:
        GFFReader(istream& in);
        ~GFFReader() = default;

        void for_each_gff_record(function<void(const GFFRecord&)>& lambda);

    private:
        istream& in;
    };

}

#endif
<commit_msg>add gcc dependencies in header<commit_after>#ifndef VG_GFF_READER_HPP_INCLUDED
#define VG_GFF_READER_HPP_INCLUDED

#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <limits>
#include <functional>

namespace vg {

    using namespace std;

    /**
     * A package of the information contained in a GFF3 record. The null "." entries in a
     * a GFF are parsed into empty strings or the default values of the numerical fields
     * as given below.
     */
    struct GFFRecord {
    public:
        GFFRecord() = default;
        ~GFFRecord() = default;

        string sequence_id;
        string source;
        string type;
        // 0-based indexing, unlike the actual GFF standard
        int64_t start = -1;
        // 0-based, inclusive
        int64_t end = -1;
        double score = numeric_limits<double>::quiet_NaN();
        bool strand_is_rev = false;
        int32_t phase = -1;
        string attributes;

        map<string, string> parse_attributes();
    };

    /**
     * A class that can parse and iterate over a GFF3 file.
     */
    class GFFReader {
    public:
        GFFReader(istream& in);
        ~GFFReader() = default;

        void for_each_gff_record(function<void(const GFFRecord&)>& lambda);

    private:
        istream& in;
    };

}

#endif
<|endoftext|>


<commit_before>#ifndef thunder_utils_path_hpp__
#define thunder_utils_path_hpp__

#include <array>
#include <iostream>

#if defined(_WIN32)
    #include <direct.h>
    #include <windows.h>
#elif defined(__linux__) || defined(__CYGWIN__)
    #include <limits.h>
    #include <unistd.h>
    #define HINSTANCE unsigned int
#else
    #error This OS is currently not supported
#endif

namespace thunder
{
namespace utils
{
namespace path
{
    inline std::string get_executable_path(HINSTANCE instance = nullptr)
    {
#if defined(_WIN32)
        constexpr auto pathlen = MAX_PATH;
#elif defined(__linux__) || defined(__CYGWIN__)
        constexpr auto pathlen = PATH_MAX;
#endif
        std::array<char, pathlen> buffer = { 0 };

#if defined(_WIN32)
        if (::GetModuleFileNameA(instance, buffer.data(), pathlen) == 0)
#elif defined(__linux__) || defined(__CYGWIN__)
        if (::readlink("/proc/self/exe", buffer, pathlen) == -1)
#endif
            std::cerr << "error while getting executable path" << std::endl;

        auto executable_path = std::string(buffer.data());
        auto executable_directory = executable_path.substr(0, executable_path.find_last_of("\\"));

        return std::move(executable_directory);
    }

    inline std::string get_working_directory()
    {
#if defined(_WIN32)
        constexpr auto pathlen = MAX_PATH;
#elif defined(__linux__) || defined(__CYGWIN__)
        constexpr auto pathlen = PATH_MAX;
#endif
        std::string working_directory{ };
        std::array<char, pathlen> buffer = { 0 };

#if defined(_WIN32)
        if ( ::_getcwd(buffer.data(), MAX_PATH) != nullptr )
            working_directory = std::string( buffer.data() );
#elif defined(__linux__) || defined(__CYGWIN__)
        if ( ::getcwd(buffer, PATH_MAX) != nullptr )
            working_directory = std::string(buffer);
#endif
        else
            std::cerr << "could not get working directory" << std::endl;

        return std::move(working_directory);
    }
};
};
};

#endif // thunder_utils_path_hpp__
<commit_msg>Make utils::path::get_working_directory more general<commit_after>#ifndef thunder_utils_path_hpp__
#define thunder_utils_path_hpp__

#include <array>
#include <iostream>

#if defined(_WIN32)
    #include <direct.h>
    #include <windows.h>
#elif defined(__linux__) || defined(__CYGWIN__)
    #include <limits.h>
    #include <unistd.h>
    #define HINSTANCE unsigned int
#else
    #error This OS is currently not supported
#endif

namespace thunder
{
namespace utils
{
namespace path
{
    inline std::string get_executable_path(HINSTANCE instance = nullptr)
    {
#if defined(_WIN32)
        constexpr auto pathlen = MAX_PATH;
#elif defined(__linux__) || defined(__CYGWIN__)
        constexpr auto pathlen = PATH_MAX;
#endif
        std::array<char, pathlen> buffer = { 0 };

#if defined(_WIN32)
        if (::GetModuleFileNameA(instance, buffer.data(), pathlen) == 0)
#elif defined(__linux__) || defined(__CYGWIN__)
        if (::readlink("/proc/self/exe", buffer, pathlen) == -1)
#endif
            std::cerr << "error while getting executable path" << std::endl;

        auto executable_path = std::string(buffer.data());
        auto executable_directory = executable_path.substr(0, executable_path.find_last_of("\\"));

        return std::move(executable_directory);
    }

    inline std::string get_working_directory()
    {
#if defined(_WIN32)
        constexpr auto pathlen = MAX_PATH;
#elif defined(__linux__) || defined(__CYGWIN__)
        constexpr auto pathlen = PATH_MAX;
#endif
        std::string working_directory{ };
        std::array<char, pathlen> buffer = { 0 };

#if defined(_WIN32)
        if ( ::_getcwd(buffer.data(), MAX_PATH) != nullptr )
			working_directory = std::string{ buffer.data() };
#elif defined(__linux__) || defined(__CYGWIN__)
        if ( ::getcwd(buffer, PATH_MAX) != nullptr )
            working_directory = std::string(buffer);
#endif
        else
            std::cerr << "could not get working directory" << std::endl;

		working_directory += '/';

        return std::move(working_directory);
    }
};
};
};

#endif // thunder_utils_path_hpp__
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <chrono>
#include <random>

#include "os/task_t.h"
#include "os/task_system_t.h"
#include "os/parse.h"
#include "os/generator.h"
#include "os/scheduler.h"
#include "lib/io.h"
#include "lib/num.h"

int main(){
	std::cout << "Hello world!" << std::endl;

	{
		os::task_t task;
		std::cout << task << std::endl;
	}

	{
		os::task_system_t task_system(5);
		std::cout << task_system << std::endl;
	}

	{
		std::ifstream ifs("system/0", std::ifstream::in);
		char c = ifs.get();
		while (ifs.good()){
			std::cout << c;
			c = ifs.get();
		}
		ifs.close();
		std::cout << '\n';
	}

	{
		os::task_system_t task_system;
		std::cout << task_system << std::endl;

		std::ifstream ifs("system/0", std::ifstream::in);
		os::parse_task_system_stream(ifs, task_system);
		ifs.close();

		std::cout << task_system << std::endl;
	}

	{
		os::task_system_t task_system;
		std::cout << task_system << std::endl;

		uint seed = std::chrono::system_clock::now().time_since_epoch().count();
		std::default_random_engine generator(seed);
		std::uniform_int_distribution<uint> distribution(0,100);
		uint usage = 70;
		uint n = 5;
		os::generate_task_system(generator, distribution, usage, n, task_system);

		std::cout << task_system << std::endl;
		uint u = 0;
		for(auto task : task_system){
			u += task.wcet;
		}

		std::cout << u << std::endl;
	}
	return 0;
}<commit_msg>clean<commit_after>#include <iostream>
#include <fstream>
#include <chrono>
#include <random>

#include "os/task_t.h"
#include "os/task_system_t.h"
#include "os/parse.h"
#include "os/generator.h"
#include "os/scheduler.h"
#include "lib/io.h"
#include "lib/num.h"

int main(){
	std::cout << "Hello world!" << std::endl;

	{
		std::cout << "TASK PRINT TEST" << std::endl;
		os::task_t task;
		std::cout << task << std::endl;
	}

	{
		std::cout << "TASK SYSTEM PRINT TEST" << std::endl;
		os::task_system_t task_system(5);
		std::cout << task_system << std::endl;
	}

	{
		std::cout << "READ FILE TEST" << std::endl;
		std::ifstream ifs("system/0", std::ifstream::in);
		char c = ifs.get();
		while (ifs.good()){
			std::cout << c;
			c = ifs.get();
		}
		ifs.close();
		std::cout << '\n';
	}

	{
		std::cout << "PARSE FILE TEST" << std::endl;
		os::task_system_t task_system;
		std::cout << task_system << std::endl;

		std::ifstream ifs("system/0", std::ifstream::in);
		os::parse_task_system_stream(ifs, task_system);
		ifs.close();

		std::cout << task_system << std::endl;
	}

	{
		std::cout << "GENERATE SYSTEM TEST" << std::endl;
		os::task_system_t task_system;
		std::cout << task_system << std::endl;

		uint seed = std::chrono::system_clock::now().time_since_epoch().count();
		std::default_random_engine generator(seed);
		std::uniform_int_distribution<uint> distribution(0,100);
		uint usage = 70;
		uint n = 5;
		os::generate_task_system(generator, distribution, usage, n, task_system);

		std::cout << task_system << std::endl;
		uint u = 0;
		for(auto task : task_system){
			u += task.wcet;
		}

		std::cout << u << std::endl;
	}

	{
		std::cout << "SCHEDULER TEST" << std::endl;

		os::task_system_t task_system;
		std::cout << task_system << std::endl;

		std::ifstream ifs("system/0", std::ifstream::in);
		os::parse_task_system_stream(ifs, task_system);
		ifs.close();

		std::cout << task_system << std::endl;
	}
	return 0;
}<|endoftext|>