<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cvtgrf.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 11:56:14 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _SV_SVSYS_HXX
#include <svsys.h>
#endif
#ifndef _SV_METAACT_HXX
#include <metaact.hxx>
#endif
#ifndef _SV_SALINST_HXX
#include <salinst.hxx>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_CVTGRF_HXX
#include <cvtgrf.hxx>
#endif

// --------------
// - Callback   -
// --------------

// --------------------
// - GraphicConverter -
// --------------------

GraphicConverter::GraphicConverter() :
    mpConvertData( NULL )
{
}

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

GraphicConverter::~GraphicConverter()
{
}

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

ULONG GraphicConverter::ImplConvert( ULONG nInFormat, void* pInBuffer, ULONG nInBufSize,
                                     void** ppOutBuffer, ULONG nOutFormat )
{
    ULONG nRetBufSize = 0UL;

    if( ( nInFormat != nOutFormat ) && pInBuffer )
    {
        if( ( nInFormat == CVT_SVM ) || ( nInFormat == CVT_BMP ) )
        {
            SvMemoryStream  aIStm;
            Graphic         aGraphic;

            aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
            aIStm >> aGraphic;

            if( !aIStm.GetError() )
            {
                SvMemoryStream aOStm( 64535, 64535 );

                mpConvertData = new ConvertData( aGraphic, aOStm, nOutFormat );

                if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
                {
                    nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
                    *ppOutBuffer = (void*) aOStm.GetData();
                    aOStm.ObjectOwnsMemory( FALSE );
                }

                delete mpConvertData;
                mpConvertData = NULL;
            }
        }
        else if( ( nOutFormat == CVT_SVM ) || ( nOutFormat == CVT_BMP ) )
        {
            SvMemoryStream  aIStm;

            aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
            mpConvertData = new ConvertData( Graphic(), aIStm, nInFormat );

            if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
            {
                SvMemoryStream  aOStm( 645535, 64535 );
                Graphic&        rGraphic = mpConvertData->maGraphic;

                if( ( rGraphic.GetType() == GRAPHIC_BITMAP ) && ( CVT_SVM == nOutFormat ) )
                {
                    GDIMetaFile aMtf;

                    aMtf.SetPrefSize( rGraphic.GetPrefSize() );
                    aMtf.SetPrefMapMode( rGraphic.GetPrefMapMode() );
                    aMtf.AddAction( new MetaBmpExScaleAction( Point(), aMtf.GetPrefSize(), rGraphic.GetBitmapEx() ) );
                    rGraphic = aMtf;
                }
                else if( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && ( CVT_BMP == nOutFormat ) )
                    rGraphic = rGraphic.GetBitmapEx();

                aOStm << rGraphic;

                if( !aOStm.GetError() )
                {
                    nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
                    *ppOutBuffer = (void*) aOStm.GetData();
                    aOStm.ObjectOwnsMemory( FALSE );
                }
            }

            delete mpConvertData;
            mpConvertData = NULL;
        }
    }

    return nRetBufSize;
}

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

ULONG GraphicConverter::Import( SvStream& rIStm, Graphic& rGraphic, ULONG nFormat )
{
    GraphicConverter*   pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
    ULONG               nRet = ERRCODE_IO_GENERAL;

    if( pCvt && pCvt->GetFilterHdl().IsSet() )
    {
        ConvertData aData( rGraphic, rIStm, nFormat );

        if( pCvt->GetFilterHdl().Call( &aData ) )
        {
            rGraphic = aData.maGraphic;
            nRet = ERRCODE_NONE;
        }
        else if( rIStm.GetError() )
            nRet = rIStm.GetError();
    }

    return nRet;
}

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

ULONG GraphicConverter::Export( SvStream& rOStm, const Graphic& rGraphic, ULONG nFormat )
{
    GraphicConverter*   pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
    ULONG               nRet = ERRCODE_IO_GENERAL;

    if( pCvt && pCvt->GetFilterHdl().IsSet() )
    {
        ConvertData aData( rGraphic, rOStm, nFormat );

        if( pCvt->GetFilterHdl().Call( &aData ) )
            nRet = ERRCODE_NONE;
        else if( rOStm.GetError() )
            nRet = rOStm.GetError();
    }

    return nRet;
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.5.378); FILE MERGED 2006/09/01 17:57:41 kaib 1.5.378.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cvtgrf.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 11:59:14 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#ifndef _SV_SVSYS_HXX
#include <svsys.h>
#endif
#ifndef _SV_METAACT_HXX
#include <metaact.hxx>
#endif
#ifndef _SV_SALINST_HXX
#include <salinst.hxx>
#endif
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _SV_CVTGRF_HXX
#include <cvtgrf.hxx>
#endif

// --------------
// - Callback   -
// --------------

// --------------------
// - GraphicConverter -
// --------------------

GraphicConverter::GraphicConverter() :
    mpConvertData( NULL )
{
}

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

GraphicConverter::~GraphicConverter()
{
}

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

ULONG GraphicConverter::ImplConvert( ULONG nInFormat, void* pInBuffer, ULONG nInBufSize,
                                     void** ppOutBuffer, ULONG nOutFormat )
{
    ULONG nRetBufSize = 0UL;

    if( ( nInFormat != nOutFormat ) && pInBuffer )
    {
        if( ( nInFormat == CVT_SVM ) || ( nInFormat == CVT_BMP ) )
        {
            SvMemoryStream  aIStm;
            Graphic         aGraphic;

            aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
            aIStm >> aGraphic;

            if( !aIStm.GetError() )
            {
                SvMemoryStream aOStm( 64535, 64535 );

                mpConvertData = new ConvertData( aGraphic, aOStm, nOutFormat );

                if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
                {
                    nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
                    *ppOutBuffer = (void*) aOStm.GetData();
                    aOStm.ObjectOwnsMemory( FALSE );
                }

                delete mpConvertData;
                mpConvertData = NULL;
            }
        }
        else if( ( nOutFormat == CVT_SVM ) || ( nOutFormat == CVT_BMP ) )
        {
            SvMemoryStream  aIStm;

            aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
            mpConvertData = new ConvertData( Graphic(), aIStm, nInFormat );

            if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
            {
                SvMemoryStream  aOStm( 645535, 64535 );
                Graphic&        rGraphic = mpConvertData->maGraphic;

                if( ( rGraphic.GetType() == GRAPHIC_BITMAP ) && ( CVT_SVM == nOutFormat ) )
                {
                    GDIMetaFile aMtf;

                    aMtf.SetPrefSize( rGraphic.GetPrefSize() );
                    aMtf.SetPrefMapMode( rGraphic.GetPrefMapMode() );
                    aMtf.AddAction( new MetaBmpExScaleAction( Point(), aMtf.GetPrefSize(), rGraphic.GetBitmapEx() ) );
                    rGraphic = aMtf;
                }
                else if( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && ( CVT_BMP == nOutFormat ) )
                    rGraphic = rGraphic.GetBitmapEx();

                aOStm << rGraphic;

                if( !aOStm.GetError() )
                {
                    nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
                    *ppOutBuffer = (void*) aOStm.GetData();
                    aOStm.ObjectOwnsMemory( FALSE );
                }
            }

            delete mpConvertData;
            mpConvertData = NULL;
        }
    }

    return nRetBufSize;
}

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

ULONG GraphicConverter::Import( SvStream& rIStm, Graphic& rGraphic, ULONG nFormat )
{
    GraphicConverter*   pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
    ULONG               nRet = ERRCODE_IO_GENERAL;

    if( pCvt && pCvt->GetFilterHdl().IsSet() )
    {
        ConvertData aData( rGraphic, rIStm, nFormat );

        if( pCvt->GetFilterHdl().Call( &aData ) )
        {
            rGraphic = aData.maGraphic;
            nRet = ERRCODE_NONE;
        }
        else if( rIStm.GetError() )
            nRet = rIStm.GetError();
    }

    return nRet;
}

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

ULONG GraphicConverter::Export( SvStream& rOStm, const Graphic& rGraphic, ULONG nFormat )
{
    GraphicConverter*   pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
    ULONG               nRet = ERRCODE_IO_GENERAL;

    if( pCvt && pCvt->GetFilterHdl().IsSet() )
    {
        ConvertData aData( rGraphic, rOStm, nFormat );

        if( pCvt->GetFilterHdl().Call( &aData ) )
            nRet = ERRCODE_NONE;
        else if( rOStm.GetError() )
            nRet = rOStm.GetError();
    }

    return nRet;
}
<|endoftext|>


<commit_before><commit_msg>deactivate print job after error<commit_after><|endoftext|>


<commit_before>/******************************************************************
 *
 * uSQL for C++
 *
 * Copyright (C) Satoshi Konno 2012
 *
 * This is licensed under BSD-style license, see file COPYING.
 *
 ******************************************************************/

#include "SQLProxy.h"
#include "MD5.h"
#include "Dictionary.h"

using namespace std;
using namespace uSQL;

uSQL::SQLProxy::SQLProxy()
{
}

uSQL::SQLProxy::~SQLProxy()
{
}

bool uSQL::SQLProxy::getKey(SQLCollection *collectionNode, SQLExpression *exprNode, std::string &key)
{
    string keyString;

    string tableName = collectionNode->getValue();
    keyString = tableName;

    string exprString;
    exprNode->toString(exprString);
    keyString.append(exprString);

    MD5::hash(keyString, key);

    return true;
}

bool uSQL::SQLProxy::getInsertStatementKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLCollection *collectionNode = stmt->getCollectionNode();
    if (!collectionNode) {
        error.setMessage("Collection was not found");
        return false;
    }

    SQLExpression exprNode;

    return getKey(collectionNode, &exprNode, key);
}

bool uSQL::SQLProxy::getStatementKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLCommand *sqlCmd = stmt->getCommandNode();
    if (!sqlCmd) {
        error.setMessage("COMMAND section was not found");
        return false;
    }

    SQLFrom *sqlFrom = stmt->getFromNode();
    if (!sqlFrom) {
        error.setMessage("FROM section was not found");
        return false;
    }

    if (sqlFrom->getChildCount() < 1) {
        error.setMessage("Data source was not found");
        return false;
    }
    if (1 < sqlFrom->getChildCount()) {
        error.setMessage("Data source is more than one");
        return false;
    }

    SQLCollection *dataSource = sqlFrom->getCollectionNode(0);

    SQLWhere *sqlWhere = stmt->getWhereNode();
    if (!sqlWhere) {
        error.setMessage("WHERE section was not found");
        return false;
    }

    if (sqlWhere->getChildCount() < 1) {
        error.setMessage("Expression was not found");
        return false;
    }

    SQLExpression *exprNode = sqlWhere->getExpressionNode(0);

    return getKey(dataSource, exprNode, key);
}

bool uSQL::SQLProxy::getKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLCommand *sqlCmd = stmt->getCommandNode();
    if (!sqlCmd) {
        error.setMessage("COMMAND section was not found");
        return false;
    }

    if (sqlCmd->isSelect())
        return getInsertStatementKey(stmt, key, error);

    return getStatementKey(stmt, key, error);
}

bool uSQL::SQLProxy::getInsertDictionary(SQLStatement *stmt, Dictionary &dictionary, SQLError &error)
{
    SQLColumn *sqlColumn = stmt->getColumnNode();
    if (!sqlColumn) {
        error.setMessage("Column section was not found");
        return false;
    }

    SQLValue *sqlValue = stmt->getValueNode();
    if (!sqlValue) {
        error.setMessage("VALUES section was not found");
        return false;
    }

    SQLNodeList *sqlColums = sqlColumn->getChildNodes();
    SQLNodeList *sqlValues = sqlValue->getChildNodes();

    if (sqlColums->size() != sqlValues->size()) {
        error.setMessage("List of values less than number of Columns");
        return false;
    }

    size_t columsCount = sqlColums->size();
    for (size_t n=0; n<columsCount; n++) {
        SQLNode *colum = sqlColums->getNode(n);
        SQLNode *value = sqlValues->getNode(n);
        dictionary.set(colum->toString(), value->toString());
    }

    return true;
}

bool uSQL::SQLProxy::getUpdateDictionary(SQLStatement *stmt, Dictionary &dictionary, SQLError &error)
{
    SQLSet *sqlSet = stmt->getSetNode();
    if (!sqlSet) {
        error.setMessage("Set section was not found");
        return false;
    }

    int dictCount = sqlSet->getDictionaryCount();
    for (int n=0; n<dictCount; n++) {
        SQLDictionary *dict = sqlSet->getDictionary(n);
        string keyName = dict->getName();
        string keyValue;
        dict->getValue()->toString(keyValue);
        dictionary.set(keyName, keyValue);
    }

    return true;
}
<commit_msg><commit_after>/******************************************************************
 *
 * uSQL for C++
 *
 * Copyright (C) Satoshi Konno 2012
 *
 * This is licensed under BSD-style license, see file COPYING.
 *
 ******************************************************************/

#include "SQLProxy.h"
#include "MD5.h"
#include "Dictionary.h"

using namespace std;
using namespace uSQL;

uSQL::SQLProxy::SQLProxy()
{
}

uSQL::SQLProxy::~SQLProxy()
{
}

bool uSQL::SQLProxy::getKey(SQLCollection *collectionNode, SQLExpression *exprNode, std::string &key)
{
    string keyString;

    string tableName = collectionNode->getValue();
    keyString = tableName;

    string exprString;
    exprNode->toString(exprString);
    keyString.append(exprString);

    MD5::hash(keyString, key);

    return true;
}

bool uSQL::SQLProxy::getInsertStatementKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLCollection *collectionNode = stmt->getCollectionNode();
    if (!collectionNode) {
        error.setMessage("Collection was not found");
        return false;
    }

    SQLExpression exprNode;

    return getKey(collectionNode, &exprNode, key);
}

bool uSQL::SQLProxy::getStatementKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLFrom *sqlFrom = stmt->getFromNode();
    if (!sqlFrom) {
        error.setMessage("FROM section was not found");
        return false;
    }

    if (sqlFrom->getChildCount() < 1) {
        error.setMessage("Data source was not found");
        return false;
    }
    if (1 < sqlFrom->getChildCount()) {
        error.setMessage("Data source is more than one");
        return false;
    }

    SQLCollection *dataSource = sqlFrom->getCollectionNode(0);

    SQLWhere *sqlWhere = stmt->getWhereNode();
    if (!sqlWhere) {
        error.setMessage("WHERE section was not found");
        return false;
    }

    if (sqlWhere->getChildCount() < 1) {
        error.setMessage("Expression was not found");
        return false;
    }

    SQLExpression *exprNode = sqlWhere->getExpressionNode(0);

    return getKey(dataSource, exprNode, key);
}

bool uSQL::SQLProxy::getKey(SQLStatement *stmt, std::string &key, SQLError &error)
{
    SQLCommand *sqlCmd = stmt->getCommandNode();
    if (!sqlCmd) {
        error.setMessage("COMMAND section was not found");
        return false;
    }

    if (sqlCmd->isSelect())
        return getInsertStatementKey(stmt, key, error);

    return getStatementKey(stmt, key, error);
}

bool uSQL::SQLProxy::getInsertDictionary(SQLStatement *stmt, Dictionary &dictionary, SQLError &error)
{
    SQLColumn *sqlColumn = stmt->getColumnNode();
    if (!sqlColumn) {
        error.setMessage("Column section was not found");
        return false;
    }

    SQLValue *sqlValue = stmt->getValueNode();
    if (!sqlValue) {
        error.setMessage("VALUES section was not found");
        return false;
    }

    SQLNodeList *sqlColums = sqlColumn->getChildNodes();
    SQLNodeList *sqlValues = sqlValue->getChildNodes();

    if (sqlColums->size() != sqlValues->size()) {
        error.setMessage("List of values less than number of Columns");
        return false;
    }

    size_t columsCount = sqlColums->size();
    for (size_t n=0; n<columsCount; n++) {
        SQLNode *colum = sqlColums->getNode(n);
        SQLNode *value = sqlValues->getNode(n);
        dictionary.set(colum->toString(), value->toString());
    }

    return true;
}

bool uSQL::SQLProxy::getUpdateDictionary(SQLStatement *stmt, Dictionary &dictionary, SQLError &error)
{
    SQLSet *sqlSet = stmt->getSetNode();
    if (!sqlSet) {
        error.setMessage("Set section was not found");
        return false;
    }

    int dictCount = sqlSet->getDictionaryCount();
    for (int n=0; n<dictCount; n++) {
        SQLDictionary *dict = sqlSet->getDictionary(n);
        string keyName = dict->getName();
        string keyValue;
        dict->getValue()->toString(keyValue);
        dictionary.set(keyName, keyValue);
    }

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDir>
#include <QHostAddress>
#include <QStringList>

#include <QFilesystemHandler>
#include <QHttpServer>

int main(int argc, char * argv[])
{
    QCoreApplication a(argc, argv);

    // Build the command-line options
    QCommandLineParser parser;
    QCommandLineOption addressOption(
        QStringList() << "a" << "address",
        "address to bind to",
        "address",
        "127.0.0.1"
    );
    parser.addOption(addressOption);
    QCommandLineOption portOption(
        QStringList() << "p" << "port",
        "port to listen on",
        "port",
        "8000"
    );
    QCommandLineOption dirOption(
        QStringList() << "d" << "directory",
        "directory to serve",
        "directory",
        QDir::homePath()
    );
    parser.addOption(dirOption);
    parser.addHelpOption();

    // Parse the options that were provided
    parser.process(a);

    // Obtain the values
    QHostAddress address = QHostAddress(parser.value(addressOption));
    quint16 port = parser.value(portOption).toInt();
    QString dir = parser.value(dirOption);

    // Create the filesystem handler and server
    QFilesystemHandler handler(dir);
    QHttpServer server(&handler);

    // Attempt to listen on the specified port
    if(!server.listen(address, port)) {
        qCritical("Unable to listen on the specified port.");
        return 1;
    }

    return a.exec();
}
<commit_msg>Added missing 'port' option to filserver example.<commit_after>/*
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDir>
#include <QHostAddress>
#include <QStringList>

#include <QFilesystemHandler>
#include <QHttpServer>

int main(int argc, char * argv[])
{
    QCoreApplication a(argc, argv);

    // Build the command-line options
    QCommandLineParser parser;
    QCommandLineOption addressOption(
        QStringList() << "a" << "address",
        "address to bind to",
        "address",
        "127.0.0.1"
    );
    parser.addOption(addressOption);
    QCommandLineOption portOption(
        QStringList() << "p" << "port",
        "port to listen on",
        "port",
        "8000"
    );
    parser.addOption(portOption);
    QCommandLineOption dirOption(
        QStringList() << "d" << "directory",
        "directory to serve",
        "directory",
        QDir::homePath()
    );
    parser.addOption(dirOption);
    parser.addHelpOption();

    // Parse the options that were provided
    parser.process(a);

    // Obtain the values
    QHostAddress address = QHostAddress(parser.value(addressOption));
    quint16 port = parser.value(portOption).toInt();
    QString dir = parser.value(dirOption);

    // Create the filesystem handler and server
    QFilesystemHandler handler(dir);
    QHttpServer server(&handler);

    // Attempt to listen on the specified port
    if(!server.listen(address, port)) {
        qCritical("Unable to listen on the specified port.");
        return 1;
    }

    return a.exec();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include "tuner_api.h"

#if defined(_MSC_VER)
    #define KTT_CL_KERNEL_FILE "../examples/gemm_batch/gemm_kernel.cl"
#else
    #define KTT_CL_KERNEL_FILE "../../examples/gemm_batch/gemm_kernel.cl"
#endif
    #if defined(_MSC_VER)
        #define KTT_CU_KERNEL_FILE "../examples/gemm_batch/gemm_kernel.cu"
    #else
        #define KTT_CU_KERNEL_FILE "../../examples/gemm_batch/gemm_kernel.cu"
    #endif

#define REAL float
#define STEPS 100

class referenceGemm : public ktt::ReferenceClass
{
public:
    referenceGemm(const std::vector<REAL>& srcA, const std::vector<REAL>& srcB, const int a, const int b, const int c, const int n, const ktt::ArgumentId resultArgumentId) :
        srcA(srcA),
	    srcB(srcB),
    	a(a),
    	b(b),
	    c(c),
    	n(n),
        resultArgumentId(resultArgumentId)
    {}

    void computeResult() override {
        res.resize(n*c*b);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < c; j++)
                for (int k = 0; k < b; k++) {
                    REAL tmp = 0.0f;
                    for (int l = 0; l < a; l++)
                        tmp += srcA[i*a*b + k*a + l] * srcB[i*c*a + l*c + j];
                    res[i*c*b + k*c + j] = tmp;
                }
            /*if (i == 0) {
                for (int bl = 0; bl < b; bl++){
                    for (int al = 0; al < a; al++)
                        std::cout << srcA[i*a*b + bl*a + al] << " ";
                    std::cout << "\n";
                }
                for (int al = 0; al < a; al++){
                    for (int cl = 0; cl < c; cl++)
                        std::cout << srcB[i*c*b + al*c + cl] << " ";
                    std::cout << "\n";
                }
                for (int bl = 0; bl < b; bl++){
                    for (int cl = 0; cl < c; cl++)
                        std::cout << res[i*c*b + bl*c + cl] << " ";
                    std::cout << "\n";
                }
            }*/
	    }
    }

    void* getData(const ktt::ArgumentId id) override {
        if (id == resultArgumentId) {
            return (void*)res.data();
        }
        return nullptr;
    }

    size_t getNumberOfElements(const ktt::ArgumentId argumentId) const override {
        return n*c*b;
    }

private:
    std::vector<REAL> res;
    std::vector<REAL> srcA;
    std::vector<REAL> srcB;
    int a, b, c, n;
    ktt::ArgumentId resultArgumentId;
};

class cTunableGemm : public ktt::TuningManipulator {
public:
    cTunableGemm(const int batch, const int a, const int b, const int c)  :
        batch(batch),
        a(a),
        b(b),
        c(c)
    {}
    void launchComputation(const ktt::KernelId kernelId) override {
        ktt::DimensionVector globalSize(1, 1, 1);
        ktt::DimensionVector localSize(1, 1, 1);
        std::vector<ktt::ParameterPair> parameterValues = getCurrentConfiguration();
        size_t gran = getParameterValue("GRANULARITY", parameterValues);
        size_t myBatch = batch / getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
        if (gran == 1) {
            globalSize.setSizeX(myBatch/getParameterValue("GROUP_SIZE_X", parameterValues));
            localSize.setSizeX(getParameterValue("GROUP_SIZE_X", parameterValues));
        }
        if (gran == 2) {
            size_t y = getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
            globalSize.setSizeX(batch / y);
            localSize.setSizeX(c);
            localSize.setSizeY(y);
        }
        if (gran == 3) {
            size_t y = getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
            globalSize.setSizeX(batch);
            localSize.setSizeX(c);
            localSize.setSizeY(y);
        }

        runKernel(kernelId, globalSize, localSize);
    }
private:
    int batch, a, b, c;
};

void tuneKernel(ktt::Tuner* tuner, std::string& kernelFile, ktt::ArgumentId& aID, ktt::ArgumentId& bID, ktt::ArgumentId &dstID, ktt::ArgumentId& nID, int a, int b, int c, int batch) {
    clock_t beginOverallTime = clock();

    // create kernel
    ktt::DimensionVector ndRangeDimensions(batch);
    ktt::DimensionVector workGroupDimensions;
    ktt::KernelId kernelId = tuner->addKernelFromFile(kernelFile, "gemm_batch", ndRangeDimensions, workGroupDimensions);

    // assign arguments
    tuner->setKernelArguments(kernelId, std::vector<ktt::ArgumentId>{aID, bID, dstID, nID});

    // create tuning space
    tuner->addParameter(kernelId, "SIZE_A", {(size_t)a});
    tuner->addParameter(kernelId, "SIZE_B", {(size_t)b});
    tuner->addParameter(kernelId, "SIZE_C", {(size_t)c});
    tuner->addParameter(kernelId, "GRANULARITY", {/*1, */2, 3}); // 1 = fine (matrix per thread), 2 = medium (block of a), 3 = coarse (block of a*b)
    tuner->addParameter(kernelId, "GROUP_SIZE_X", {1, 32, 64, 128, 256, 512});
    tuner->addParameter(kernelId, "MGCG_GROUP_SIZE_X", {1, (size_t)c});
    tuner->addParameter(kernelId, "MGCG_GROUP_SIZE_Y", {1, 2, 4, 8, 16, 32});
    tuner->addParameter(kernelId, "CACHING_STRATEGY", {0, 1, 2}); /* 0 = implicit caching, 1 = local memory, 2 = private memory */
    auto parallelismConstraint = [](const std::vector<size_t>& v) {return (v[0] == 1 && v[1] > 1 && v[2] == 1 && v[3] == 1) || (v[0] == 2 && v[1] == 1 && v[2] > 1) || (v[0] == 3 && v[1] == 1 && v[2] > 1);};
    tuner->addConstraint(kernelId, parallelismConstraint, {"GRANULARITY", "GROUP_SIZE_X", "MGCG_GROUP_SIZE_X", "MGCG_GROUP_SIZE_Y"});
    auto tmpConstraint = [](const std::vector<size_t>& v) {return (v[0] < 3 || v[1] < 2);};
    tuner->addConstraint(kernelId, tmpConstraint, {"GRANULARITY", "CACHING_STRATEGY"});
    auto smConstraint = [](const std::vector<size_t>& v) {return (v[0] != 2) || (v[1]*v[2] + v[3]*v[1] + v[3]*v[2])*v[4]*sizeof(REAL) < 48*1024;};
    tuner->addConstraint(kernelId, smConstraint, {"GRANULARITY", "SIZE_A", "SIZE_B", "SIZE_C", "MGCG_GROUP_SIZE_Y"});

    // assign manipulator
    tuner->setTuningManipulator(kernelId, std::make_unique<cTunableGemm>(batch, a, b, c));

    // tune kernel
    std::vector<REAL> firstMatrix(32*32);
    ktt::OutputDescriptor output(dstID, (void*)firstMatrix.data(), 32*32*sizeof(REAL));
    for (int i = 0; i < STEPS; i++) {
        tuner->tuneKernelByStep(kernelId, {output});
        clock_t now = clock();
        double overallSec = double(now - beginOverallTime) / CLOCKS_PER_SEC;
        double perfActual = 0.0;
        double effActual = 0.0;
        double perfOverall = (double)((i+1)*a*b*c*2)*(double)batch / overallSec / 1000000000.0;
        std::cout << overallSec << std::endl;
        std::cout << "Actual perf. " << perfActual << "GFlops, "
            << "actual BW " << effActual << "GB/s, "
            << "perf. with overhead " << perfOverall << "GFlops" << std::endl;
    }

    // print best
    std::pair<std::vector<ktt::ParameterPair>, double> bestConf = tuner->getBestConfiguration(kernelId);
    std::cout << "Performance: " << (double)(a*b*c*2)*(double)batch / std::get<1>(bestConf) << " GFlops" << std::endl;
    std::cout << "Memory BW: " << (double)(a*b+c*a+c*b)*(double)(batch)*(double)sizeof(REAL) / std::get<1>(bestConf) << " GB/s" << std::endl;
}

int main(int argc, char** argv)
{
    // Initialize platform and device index
    ktt::PlatformIndex platformIndex = 0;
    ktt::DeviceIndex deviceIndex = 0;
    std::string kernelFile;

    if (argc >= 2)
    {
        platformIndex = std::stoul(std::string(argv[1]));
        if (argc >= 3)
        {
            deviceIndex = std::stoul(std::string(argv[2]));
        }
    }

    // Declare and initialize data (m, n > 1)
    unsigned int a = 32;
    unsigned int b = 32;
    unsigned int c = 32;
    int batch = 1024*128;

    std::vector<REAL> srcA(a*b*batch, 0.0f);
    std::vector<REAL> srcB(c*a*batch, 0.0f);
    std::vector<REAL> dst(c*b*batch, 0.0f);

    // fill with random data
    for (size_t i = 0; i < a*b*batch; i++)
    {
        srcA[i] = 10.0f*((REAL)rand()) / ((REAL) RAND_MAX);
    }
    for (size_t i = 0; i < c*a*batch; i++)
    {
        srcB[i] = 10.0f*((REAL)rand()) / ((REAL) RAND_MAX);
    }

    int interface = 0;
    std::cout << "Which interface to use (0 = CUDA, 1 = OpenCL)? ";
    std::cin >> interface;

    // create and configure tunner
    ktt::Tuner* tuner = NULL;
    if (interface == 1) {
        tuner = new ktt::Tuner(platformIndex, deviceIndex);
        kernelFile = KTT_CL_KERNEL_FILE;
    }
    else {
        tuner = new ktt::Tuner(0, deviceIndex, ktt::ComputeAPI::CUDA);
        kernelFile = KTT_CU_KERNEL_FILE;
    }
    tuner->setGlobalSizeType(ktt::GlobalSizeType::CUDA);
    //tuner->setLoggingTarget(std::string("/dev/null"));

    // create input/output
    ktt::ArgumentId srcAId = tuner->addArgumentVector(srcA, ktt::ArgumentAccessType::ReadOnly);
    ktt::ArgumentId srcBId = tuner->addArgumentVector(srcB, ktt::ArgumentAccessType::ReadOnly);
    ktt::ArgumentId dstId = tuner->addArgumentVector(dst, ktt::ArgumentAccessType::WriteOnly);
    ktt::ArgumentId nId = tuner->addArgumentScalar(batch);

    // tune kernels for different sizes
    for (int i = 0; i < 10; i++) {
        a = (long long)(rand())*32 / RAND_MAX;
        b = (long long)(rand())*32 / RAND_MAX;
        c = (long long)(rand())*32 / RAND_MAX;
        std::cout << "Tuning for matrices of size "
            << a << "x" << b << ", "
            << c << "x" << a << ", "
            << c << "x" << b << std::endl;
        tuneKernel(tuner, kernelFile, srcAId, srcBId, dstId, nId, a, b, c, batch);
    }

    delete tuner;

    return 0;
}
<commit_msg>reworked argument handling (will run out of GPU memory in current implementation)<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include "tuner_api.h"

#if defined(_MSC_VER)
    #define KTT_CL_KERNEL_FILE "../examples/gemm_batch/gemm_kernel.cl"
#else
    #define KTT_CL_KERNEL_FILE "../../examples/gemm_batch/gemm_kernel.cl"
#endif
    #if defined(_MSC_VER)
        #define KTT_CU_KERNEL_FILE "../examples/gemm_batch/gemm_kernel.cu"
    #else
        #define KTT_CU_KERNEL_FILE "../../examples/gemm_batch/gemm_kernel.cu"
    #endif

#define REAL float
#define STEPS 1000
#define MAX_MEM 900000000

class referenceGemm : public ktt::ReferenceClass
{
public:
    referenceGemm(const std::vector<REAL>& srcA, const std::vector<REAL>& srcB, const int a, const int b, const int c, const int n, const ktt::ArgumentId resultArgumentId) :
        srcA(srcA),
	    srcB(srcB),
    	a(a),
    	b(b),
	    c(c),
    	n(n),
        resultArgumentId(resultArgumentId)
    {}

    void computeResult() override {
        res.resize(n*c*b);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < c; j++)
                for (int k = 0; k < b; k++) {
                    REAL tmp = 0.0f;
                    for (int l = 0; l < a; l++)
                        tmp += srcA[i*a*b + k*a + l] * srcB[i*c*a + l*c + j];
                    res[i*c*b + k*c + j] = tmp;
                }
            /*if (i == 0) {
                for (int bl = 0; bl < b; bl++){
                    for (int al = 0; al < a; al++)
                        std::cout << srcA[i*a*b + bl*a + al] << " ";
                    std::cout << "\n";
                }
                for (int al = 0; al < a; al++){
                    for (int cl = 0; cl < c; cl++)
                        std::cout << srcB[i*c*b + al*c + cl] << " ";
                    std::cout << "\n";
                }
                for (int bl = 0; bl < b; bl++){
                    for (int cl = 0; cl < c; cl++)
                        std::cout << res[i*c*b + bl*c + cl] << " ";
                    std::cout << "\n";
                }
            }*/
	    }
    }

    void* getData(const ktt::ArgumentId id) override {
        if (id == resultArgumentId) {
            return (void*)res.data();
        }
        return nullptr;
    }

    size_t getNumberOfElements(const ktt::ArgumentId argumentId) const override {
        return n*c*b;
    }

private:
    std::vector<REAL> res;
    std::vector<REAL> srcA;
    std::vector<REAL> srcB;
    int a, b, c, n;
    ktt::ArgumentId resultArgumentId;
};

class cTunableGemm : public ktt::TuningManipulator {
public:
    cTunableGemm(const int batch, const int a, const int b, const int c)  :
        batch(batch),
        a(a),
        b(b),
        c(c)
    {}
    void launchComputation(const ktt::KernelId kernelId) override {
        ktt::DimensionVector globalSize(1, 1, 1);
        ktt::DimensionVector localSize(1, 1, 1);
        std::vector<ktt::ParameterPair> parameterValues = getCurrentConfiguration();
        size_t gran = getParameterValue("GRANULARITY", parameterValues);
        size_t myBatch = batch / getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
        std::cout << "batch: " << batch << std::endl;
        if (gran == 1) {
            globalSize.setSizeX(myBatch/getParameterValue("GROUP_SIZE_X", parameterValues));
            localSize.setSizeX(getParameterValue("GROUP_SIZE_X", parameterValues));
        }
        if (gran == 2) {
            size_t y = getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
            globalSize.setSizeX(batch / y);
            localSize.setSizeX(c);
            localSize.setSizeY(y);
        }
        if (gran == 3) {
            size_t y = getParameterValue("MGCG_GROUP_SIZE_Y", parameterValues);
            globalSize.setSizeX(batch);
            localSize.setSizeX(c);
            localSize.setSizeY(y);
        }

        runKernel(kernelId, globalSize, localSize);
    }
private:
    int batch, a, b, c;
};

void tuneKernel(ktt::Tuner* tuner, std::string& kernelFile, ktt::ArgumentId& aID, ktt::ArgumentId& bID, ktt::ArgumentId &dstID, ktt::ArgumentId& nID, int a, int b, int c, int batch) {
    clock_t beginOverallTime = clock();

    // create kernel
    ktt::DimensionVector ndRangeDimensions(batch);
    ktt::DimensionVector workGroupDimensions;
    ktt::KernelId kernelId = tuner->addKernelFromFile(kernelFile, "gemm_batch", ndRangeDimensions, workGroupDimensions);

    // assign arguments
    tuner->setKernelArguments(kernelId, std::vector<ktt::ArgumentId>{aID, bID, dstID, nID});

    // create tuning space
    tuner->addParameter(kernelId, "SIZE_A", {(size_t)a});
    tuner->addParameter(kernelId, "SIZE_B", {(size_t)b});
    tuner->addParameter(kernelId, "SIZE_C", {(size_t)c});
    tuner->addParameter(kernelId, "GRANULARITY", {/*1, */2, 3}); // 1 = fine (matrix per thread), 2 = medium (block of a), 3 = coarse (block of a*b)
    tuner->addParameter(kernelId, "GROUP_SIZE_X", {1, 32, 64, 128, 256, 512});
    tuner->addParameter(kernelId, "MGCG_GROUP_SIZE_X", {1, (size_t)c});
    tuner->addParameter(kernelId, "MGCG_GROUP_SIZE_Y", {1, 2, 4, 8, 16, 32});
    tuner->addParameter(kernelId, "CACHING_STRATEGY", {0, 1, 2}); /* 0 = implicit caching, 1 = local memory, 2 = private memory */
    auto parallelismConstraint = [](const std::vector<size_t>& v) {return (v[0] == 1 && v[1] > 1 && v[2] == 1 && v[3] == 1) || (v[0] == 2 && v[1] == 1 && v[2] > 1) || (v[0] == 3 && v[1] == 1 && v[2] > 1);};
    tuner->addConstraint(kernelId, parallelismConstraint, {"GRANULARITY", "GROUP_SIZE_X", "MGCG_GROUP_SIZE_X", "MGCG_GROUP_SIZE_Y"});
    auto tmpConstraint = [](const std::vector<size_t>& v) {return (v[0] < 3 || v[1] < 2);};
    tuner->addConstraint(kernelId, tmpConstraint, {"GRANULARITY", "CACHING_STRATEGY"});
    auto smConstraint = [](const std::vector<size_t>& v) {return (v[0] != 2) || (v[1]*v[2] + v[3]*v[1] + v[3]*v[2])*v[4]*sizeof(REAL) < 48*1024;};
    tuner->addConstraint(kernelId, smConstraint, {"GRANULARITY", "SIZE_A", "SIZE_B", "SIZE_C", "MGCG_GROUP_SIZE_Y"});

    // assign manipulator
    tuner->setTuningManipulator(kernelId, std::make_unique<cTunableGemm>(batch, a, b, c));

    // tune kernel
    std::vector<REAL> firstMatrix(32*32);
    ktt::OutputDescriptor output(dstID, (void*)firstMatrix.data(), 32*32*sizeof(REAL));
    for (int i = 0; i < STEPS; i++) {
        tuner->tuneKernelByStep(kernelId, {output});
        clock_t now = clock();
        double overallSec = double(now - beginOverallTime) / CLOCKS_PER_SEC;
        double perfActual = 0.0;
        double effActual = 0.0;
        double perfOverall = (double)((i+1)*a*b*c*2)*(double)batch / overallSec / 1000000000.0;
        std::cout << overallSec << std::endl;
        std::cout << "Actual perf. " << perfActual << "GFlops, "
            << "actual BW " << effActual << "GB/s, "
            << "perf. with overhead " << perfOverall << "GFlops" << std::endl;
    }

    // print best
    std::pair<std::vector<ktt::ParameterPair>, double> bestConf = tuner->getBestConfiguration(kernelId);
    std::cout << "Performance: " << (double)(a*b*c*2)*(double)batch / std::get<1>(bestConf) << " GFlops" << std::endl;
    std::cout << "Memory BW: " << (double)(a*b+c*a+c*b)*(double)(batch)*(double)sizeof(REAL) / std::get<1>(bestConf) << " GB/s" << std::endl;
}

int main(int argc, char** argv)
{
    // Initialize platform and device index
    ktt::PlatformIndex platformIndex = 0;
    ktt::DeviceIndex deviceIndex = 0;
    std::string kernelFile;

    if (argc >= 2)
    {
        platformIndex = std::stoul(std::string(argv[1]));
        if (argc >= 3)
        {
            deviceIndex = std::stoul(std::string(argv[2]));
        }
    }

    int interface = 0;
    std::cout << "Which interface to use (0 = CUDA, 1 = OpenCL)? ";
    std::cin >> interface;

    // create and configure tunner
    ktt::Tuner* tuner = NULL;
    if (interface == 1) {
        tuner = new ktt::Tuner(platformIndex, deviceIndex);
        kernelFile = KTT_CL_KERNEL_FILE;
    }
    else {
        tuner = new ktt::Tuner(0, deviceIndex, ktt::ComputeAPI::CUDA);
        kernelFile = KTT_CU_KERNEL_FILE;
    }
    tuner->setGlobalSizeType(ktt::GlobalSizeType::CUDA);
    tuner->setLoggingTarget(std::string("/dev/null"));

    // tune kernels for different sizes
    for (int i = 0; i < 10; i++) {
        // generate input size
        int a = 2+(long long)(rand())*31 / RAND_MAX;
        int b = 2+(long long)(rand())*31 / RAND_MAX;
        int c = 2+(long long)(rand())*31 / RAND_MAX;
        int batch = ((MAX_MEM/(sizeof(REAL)*(a*b+c*a+c*b)))/512)*512;

        std::cout << "Tuning for matrices of size "
            << a << "x" << b << ", "
            << c << "x" << a << ", "
            << c << "x" << b << ", "
            << "batch size " << batch << std::endl;

        // create data in host memory
        std::vector<REAL> srcA(a*b*batch, 0.0f);
        std::vector<REAL> srcB(c*a*batch, 0.0f);
        std::vector<REAL> dst(c*b*batch, 0.0f);

        // fill with random values
        for (size_t i = 0; i < a*b*batch; i++)
            srcA[i] = 10.0f*((REAL)rand()) / ((REAL) RAND_MAX);
        for (size_t i = 0; i < c*a*batch; i++)
            srcB[i] = 10.0f*((REAL)rand()) / ((REAL) RAND_MAX);

        // create input/output
        ktt::ArgumentId srcAId = tuner->addArgumentVector(srcA, ktt::ArgumentAccessType::ReadOnly, ktt::ArgumentMemoryLocation::Device, false);
        tuner->persistArgument(srcAId, true);
        ktt::ArgumentId srcBId = tuner->addArgumentVector(srcB, ktt::ArgumentAccessType::ReadOnly, ktt::ArgumentMemoryLocation::Device, false);
        tuner->persistArgument(srcBId, true);
        ktt::ArgumentId dstId = tuner->addArgumentVector(dst, ktt::ArgumentAccessType::WriteOnly, ktt::ArgumentMemoryLocation::Device, false);
        tuner->persistArgument(dstId, true);
        ktt::ArgumentId nId = tuner->addArgumentScalar(batch);

        tuneKernel(tuner, kernelFile, srcAId, srcBId, dstId, nId, a, b, c, batch);
    }

    delete tuner;

    return 0;
}
<|endoftext|>


<commit_before>/**
 * toolchain-parallax_p8x32a
 *
 * Copyright 2017 Andrew Countryman <apcountryman@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

/**
 * \file main.c
 * \brief Blink C++ example program.
 */

#include <propeller.h>
#include <stdint.h>
#include <limits.h>

/**
 * \brief A LED.
 */
class LED {
    public:
        /**
         * \brief Acquire the pin resources associated with the LED, record their initial
         *        state, and drive the LED low.
         *
         * \param[in] pin The pin the LED is connected to. If pin is greater than 31, the
         *            LED will be non-responsive. Ideally this would result in an
         *            exception being thrown but that would result in the example being
         *            too large for the smaller memory models.
         */
        LED( unsigned int const pin );

        /**
         * \brief Release the pin resources associated with the LED, restoring them to
         *        their prior state.
         */
        ~LED();

        /**
         * \brief Toggle the state of the LED.
         */
        void toggle( void );

    private:
        /**
         * \brief Default construction prohibited.
         */
        LED();

        /**
         * \brief Copy construction prohibited.
         */
        LED( LED const & led );

        /**
         * \brief Copy assignment prohibited.
         */
        LED & operator=( LED const & led );

        /**
         * \brief Bit mask for interacting with the I/O registers.
         */
        uint32_t const mask_;

        /**
         * \brief The state of the DIRA when it was acquired.
         */
        uint32_t const dira_initial_;

        /**
         * \brief The state of the OUTA when it was acquired.
         */
        uint32_t const outa_initial_;
};

LED::LED( unsigned int const pin ) :
    mask_( 1 << pin ),
    dira_initial_( DIRA ),
    outa_initial_( OUTA )
{
    // configure the pin as an output, initially driven low
    OUTA &= ~mask_;
    DIRA |=  mask_;

    return;
}

LED::~LED()
{
    // restore the pin resources to their prior state
    if ( dira_initial_ & mask_ ) { DIRA |=  mask_; }
    else                         { DIRA &= ~mask_; }

    if ( outa_initial_ & mask_ ) { OUTA |=  mask_; }
    else                         { OUTA &= ~mask_; }

    return;
}

void LED::toggle( void )
{
    // toggle the state of the LED
    OUTA ^= mask_;

    return;
}

/**
 * \brief Convert a period in milliseconds to a number of clock ticks.
 *
 * \param[in] The period, in milliseconds to convert.
 *
 * \return The number of clock ticks in period.
 */
static uint32_t ms_to_ticks( unsigned int ms )
{
    return ( CLKFREQ / 1000U ) * ms;
}

/**
 * \brief Blink a LED.
 *
 * \param[in] led The LED to blink.
 * \param[in] n The number of times to blink the LED. If n is 0, the LED will be blinked
 *            infinitely. If n is greater than UINT_MAX / 2, no LED will be blinked.
 * \param[in] period The blinking period in milliseconds. If period is less than 2, no LED
 *            will be blinked.
 */
static void blink( LED & led, unsigned int n, unsigned int period )
{
    // ensure function pre-conditions are met
    bool error = n > UINT_MAX / 2 ? true
               : period < 2       ? true
                                  : false;

    if ( error ) { return; }

    // initialize the timing parameters
    uint32_t const half_period_ticks = ms_to_ticks( period / 2 );
    uint32_t next_cnt                = half_period_ticks + CNT;

    // blink the LED
    for ( unsigned int i = 0; n == 0 || i < 2 * n; ++i ) {
        // wait half a period
        next_cnt = waitcnt2( next_cnt, half_period_ticks );

        // toggle the state of the LED
        led.toggle();

    } // for

    return;
}

/**
 * \brief Main loop.
 *
 * \return N/A, enters an infinite loop once blinking is complete.
 */
int main( void )
{
    // create a new scope so that the LED will be destructed when no longer needed
    {
        // create and configure the LED
        LED led( BLINK_PIN );

        // blink the LED
        blink( led, BLINK_CNT, BLINK_PERIOD );
    }

    // infinite loop
    for ( ;; ) {}

    return 0;
}
<commit_msg>Fix example program documentation<commit_after>/**
 * toolchain-parallax_p8x32a
 *
 * Copyright 2017 Andrew Countryman <apcountryman@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

/**
 * \file main.c
 * \brief Blink C++ example program.
 */

#include <propeller.h>
#include <stdint.h>
#include <limits.h>

/**
 * \brief A LED.
 */
class LED {
    public:
        /**
         * \brief Acquire the pin resources associated with the LED, record their initial
         *        state, and drive the LED low.
         *
         * \param[in] pin The pin the LED is connected to. If pin is greater than 31, the
         *            LED will be non-responsive. Ideally this would result in an
         *            exception being thrown but that would result in the example being
         *            too large for the smaller memory models.
         */
        LED( unsigned int const pin );

        /**
         * \brief Release the pin resources associated with the LED, restoring them to
         *        their prior state.
         */
        ~LED();

        /**
         * \brief Toggle the state of the LED.
         */
        void toggle( void );

    private:
        /**
         * \brief Default construction prohibited.
         */
        LED();

        /**
         * \brief Copy construction prohibited.
         */
        LED( LED const & led );

        /**
         * \brief Copy assignment prohibited.
         */
        LED & operator=( LED const & led );

        /**
         * \brief Bit mask for interacting with the I/O registers.
         */
        uint32_t const mask_;

        /**
         * \brief The state of the DIRA when it was acquired.
         */
        uint32_t const dira_initial_;

        /**
         * \brief The state of the OUTA when it was acquired.
         */
        uint32_t const outa_initial_;
};

LED::LED( unsigned int const pin ) :
    mask_( 1 << pin ),
    dira_initial_( DIRA ),
    outa_initial_( OUTA )
{
    // configure the pin as an output, initially driven low
    OUTA &= ~mask_;
    DIRA |=  mask_;

    return;
}

LED::~LED()
{
    // restore the pin resources to their prior state
    if ( dira_initial_ & mask_ ) { DIRA |=  mask_; }
    else                         { DIRA &= ~mask_; }

    if ( outa_initial_ & mask_ ) { OUTA |=  mask_; }
    else                         { OUTA &= ~mask_; }

    return;
}

void LED::toggle( void )
{
    // toggle the state of the LED
    OUTA ^= mask_;

    return;
}

/**
 * \brief Convert a period in milliseconds to a number of clock ticks.
 *
 * \param[in] ms The period, in milliseconds, to convert.
 *
 * \return The number of clock ticks in period.
 */
static uint32_t ms_to_ticks( unsigned int ms )
{
    return ( CLKFREQ / 1000U ) * ms;
}

/**
 * \brief Blink a LED.
 *
 * \param[in] led The LED to blink.
 * \param[in] n The number of times to blink the LED. If n is 0, the LED will be blinked
 *            infinitely. If n is greater than UINT_MAX / 2, no LED will be blinked.
 * \param[in] period The blinking period in milliseconds. If period is less than 2, no LED
 *            will be blinked.
 */
static void blink( LED & led, unsigned int n, unsigned int period )
{
    // ensure function pre-conditions are met
    bool error = n > UINT_MAX / 2 ? true
               : period < 2       ? true
                                  : false;

    if ( error ) { return; }

    // initialize the timing parameters
    uint32_t const half_period_ticks = ms_to_ticks( period / 2 );
    uint32_t next_cnt                = half_period_ticks + CNT;

    // blink the LED
    for ( unsigned int i = 0; n == 0 || i < 2 * n; ++i ) {
        // wait half a period
        next_cnt = waitcnt2( next_cnt, half_period_ticks );

        // toggle the state of the LED
        led.toggle();

    } // for

    return;
}

/**
 * \brief Main loop.
 *
 * \return N/A, enters an infinite loop once blinking is complete.
 */
int main( void )
{
    // create a new scope so that the LED will be destructed when no longer needed
    {
        // create and configure the LED
        LED led( BLINK_PIN );

        // blink the LED
        blink( led, BLINK_CNT, BLINK_PERIOD );
    }

    // infinite loop
    for ( ;; ) {}

    return 0;
}
<|endoftext|>


<commit_before>// Demonstration of a single-threaded client

#include <cstdio>
#include <boost/lexical_cast.hpp>
#include "randexample/randexample.pb.h"
#include "client.hpp"

int main(int argc, char **argv) {
  if (argc != 3) {
    printf ("usage: %s <nMessage> <nSample>\n", "cmdclient");
    return 1;
  }
  int nMessage = boost::lexical_cast<int>(argv[1]);
  int nSample  = boost::lexical_cast<int>(argv[2]);

  urpc::Client client;
  randexample::Request request;
  randexample::Reply reply;

  request.set_nmessage (nMessage);
  request.set_nsample (nSample);
  client.sendRequest("Rand", 1, request);
  printf("[Rand] (nMesage=%d,nSample=%d)\n", nMessage, nSample);

  bool isMore;
  do {
    isMore = client.getReply (reply);

    printf ("Reply block:\n");
    for (int i = 0; i < reply.r_size(); i++) {
      printf("%f\n", reply.r(i));
    }
    reply.Clear();
  } while (isMore);

  return 0;
}
<commit_msg>config moved to construction<commit_after>// Demonstration of a single-threaded client

#include <cstdio>
#include <boost/lexical_cast.hpp>
#include "randexample/randexample.pb.h"
#include "client.hpp"

int main(int argc, char **argv) {
  if (argc != 3) {
    printf ("usage: %s <nMessage> <nSample>\n", "cmdclient");
    return 1;
  }
  int nMessage = boost::lexical_cast<int>(argv[1]);
  int nSample  = boost::lexical_cast<int>(argv[2]);

  urpc::Client client ("tcp://127.0.0.1:5555");
  randexample::Request request;
  randexample::Reply reply;

  request.set_nmessage (nMessage);
  request.set_nsample (nSample);
  client.sendRequest("Rand", 1, request);
  printf("[Rand] (nMesage=%d,nSample=%d)\n", nMessage, nSample);

  bool isMore;
  do {
    isMore = client.getReply (reply);

    printf ("Reply block:\n");
    for (int i = 0; i < reply.r_size(); i++) {
      printf("%f\n", reply.r(i));
    }
    reply.Clear();
  } while (isMore);

  return 0;
}
<|endoftext|>


<commit_before>#include "../opencp.hpp"
#include <fstream>
using namespace std;

void guiJointBirateralFilterTest(Mat& src, Mat& guide)
{
	Mat dest,dest2;

	string wname = "joint birateral filter";
	namedWindow(wname);

	int a=0;createTrackbar("a",wname,&a,100);
	int sw = 0; createTrackbar("switch",wname,&sw, 1);
	int r = 20; createTrackbar("r",wname,&r,200);
	int space = 200; createTrackbar("space",wname,&space,2000);
	int color = 300; createTrackbar("color",wname,&color,2550);
	int key = 0;
	Mat show;

	while(key!='q')
	{
		cout<<"r="<<r<<": "<<"please change 'sw' for changing the type of implimentations."<<endl;
		double sigma_color = color/10.0;
		double sigma_space = space/10.0;
		int d = 2*r+1;

		if(sw==0)
		{
			CalcTime t("birateral filter: opencv");
			jointBilateralFilter(src, guide, dest, Size(d,d), sigma_color, sigma_space);
		}
		if(sw==1)
		{
			CalcTime t("birateral filter: fastest opencp implimentation");
			jointBilateralFilter(guide, src, dest, Size(d,d), sigma_color, sigma_space);
		}

		patchBlendImage(src,dest,dest,Scalar(255,255,255));
		alphaBlend(src, dest,a/100.0, show);
		imshow(wname,show);
		key = waitKey(1);
	}
}

/*
void timeBirateralTest(Mat& src)
{
	int iteration = 10;
	Mat dest;

	ofstream out("birateraltime.csv");

	double time_opencv;
	double time_opencp;
	double time_opencp_sp;
	double time_opencp_sl;
	for(int r=0;r<200;r++)
	{
		cout<<"r:"<<r<<" :";
		int d = 2*r+1;
		double sigma_color = 30.0;
		double sigma_space = d/3.0;

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, d, sigma_color, sigma_space);
				st.push_back(t.getTime());
			}
			time_opencv=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_DEFAULT);
				st.push_back(t.getTime());
			}
			time_opencp=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_SEPARABLE);
				st.push_back(t.getTime());
			}
			time_opencp_sp=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_SLOWEST);
				st.push_back(t.getTime());
			}
			time_opencp_sl=st.getMedian();
		}

		out<<time_opencv<<","<<time_opencp<<","<<time_opencp_sp<<","<<time_opencp_sl<<endl;
		cout<<time_opencv<<","<<time_opencp<<","<<time_opencp_sp<<","<<time_opencp_sl<<","<<endl;
	}
}
*/<commit_msg>update joint birateral fiilter test<commit_after>#include "../opencp.hpp"
#include <fstream>
using namespace std;

void guiJointBirateralFilterTest(Mat& src, Mat& guide)
{
	Mat dest,dest2;

	string wname = "joint birateral filter";
	namedWindow(wname);

	int a=0;createTrackbar("a",wname,&a,100);
	int sw = 1; createTrackbar("switch",wname,&sw, 2);
	int r = 20; createTrackbar("r",wname,&r,200);
	int space = 200; createTrackbar("space",wname,&space,2000);
	int color = 300; createTrackbar("color",wname,&color,2550);
	int key = 0;
	Mat show;

	while(key!='q')
	{
		cout<<"r="<<r<<": "<<"please change 'sw' for changing the type of implimentations."<<endl;
		double sigma_color = color/10.0;
		double sigma_space = space/10.0;
		int d = 2*r+1;

		if(sw==0)
		{
			CalcTime t("birateral filter");
			bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space);
		}
		if(sw==1)
		{
			CalcTime t("joint birateral filter");
			jointBilateralFilter(src, guide, dest, Size(d,d), sigma_color, sigma_space);
		}
		if(sw==2)
		{
			CalcTime t("invalid joiont");
			jointBilateralFilter(guide, src, dest, Size(d,d), sigma_color, sigma_space);
		}

		patchBlendImage(src,dest,dest,Scalar(255,255,255));
		alphaBlend(src, dest,a/100.0, show);
		imshow(wname,show);
		key = waitKey(1);
	}
}

/*
void timeBirateralTest(Mat& src)
{
	int iteration = 10;
	Mat dest;

	ofstream out("birateraltime.csv");

	double time_opencv;
	double time_opencp;
	double time_opencp_sp;
	double time_opencp_sl;
	for(int r=0;r<200;r++)
	{
		cout<<"r:"<<r<<" :";
		int d = 2*r+1;
		double sigma_color = 30.0;
		double sigma_space = d/3.0;

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, d, sigma_color, sigma_space);
				st.push_back(t.getTime());
			}
			time_opencv=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_DEFAULT);
				st.push_back(t.getTime());
			}
			time_opencp=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_SEPARABLE);
				st.push_back(t.getTime());
			}
			time_opencp_sp=st.getMedian();
		}

		{
			Stat st;
			for(int i=0;i<iteration;i++)
			{
				CalcTime t("time",TIME_SEC,false);
				bilateralFilter(src, dest, Size(d,d), sigma_color, sigma_space, BILATERAL_SLOWEST);
				st.push_back(t.getTime());
			}
			time_opencp_sl=st.getMedian();
		}

		out<<time_opencv<<","<<time_opencp<<","<<time_opencp_sp<<","<<time_opencp_sl<<endl;
		cout<<time_opencv<<","<<time_opencp<<","<<time_opencp_sp<<","<<time_opencp_sl<<","<<endl;
	}
}
*/<|endoftext|>


<commit_before>void AliAnalysisTaskSEVertexingHFTest()
{
  //
  // Test macro for the AliAnalysisTaskSE for heavy-flavour vertexing
  // A.Dainese, andrea.dainese@lnl.infn.it
  //

  Bool_t inputAOD=kTRUE; // otherwise, ESD
  Bool_t createAOD=kFALSE; // kTRUE: create AOD and use it as input to vertexing
                          // kFALSE: use ESD as input to vertexing
  Bool_t writeKineToAOD = kTRUE;
  TString mode="local"; // otherwise, "grid"
  Bool_t useParFiles=kFALSE;

  gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/macros/LoadLibraries.C");
  LoadLibraries(useParFiles);

  TChain *chain = 0;

  if(mode=="local") {
    // Local files
    TString treeName,fileName;
    if(inputAOD) {
      treeName="aodTree";
      fileName="AliAOD.root";
    } else {
      treeName="esdTree";
      fileName="AliESDs.root";
    }
    chain = new TChain(treeName.Data());
    chain->Add(fileName.Data());

  } else if (mode=="grid") {
    //Fetch files with AliEn :
    const char *collectionfile = "Collection.xml";
    TGrid::Connect("alien://") ;
    TAlienCollection *coll   = TAlienCollection::Open(collectionfile);
    if(inputAOD) { // input AOD
      chain = new TChain("aodTree");
      while(coll->Next()) chain->Add(coll->GetTURL(""));
    } else { // input ESD
      //Create an AliRunTagCuts and an AliEventTagCuts Object and impose some selection criteria
      AliRunTagCuts      *runCuts   = new AliRunTagCuts();
      AliEventTagCuts    *eventCuts = new AliEventTagCuts();
      AliLHCTagCuts      *lhcCuts   = new AliLHCTagCuts();
      AliDetectorTagCuts *detCuts   = new AliDetectorTagCuts();
      eventCuts->SetMultiplicityRange(0,20000);
      //Create an AliTagAnalysis Object and chain the tags
      AliTagAnalysis   *tagAna = new AliTagAnalysis();
      tagAna->SetType("ESD");
      TGridResult      *tagResult = coll->GetGridResult("",0,0);
      tagResult->Print();
      tagAna->ChainGridTags(tagResult);
      //Create a new esd chain and assign the chain that is returned by querying the tags
      chain = tagAna->QueryTags(runCuts,lhcCuts,detCuts,eventCuts);
    }
  } else {
    printf("ERROR: mode has to be \"local\" or \"grid\" \n");
    return;
  }

  // Create the analysis manager
  AliAnalysisManager *mgr  = new AliAnalysisManager("My Manager","My Manager");
  mgr->SetDebugLevel(10);

  // Input Handler
  AliInputEventHandler *inputHandler = 0;
  if(inputAOD) {
    inputHandler = new AliAODInputHandler();
  } else {
    inputHandler = new AliESDInputHandler();
  }
  mgr->SetInputEventHandler(inputHandler);

  // Output
  AliAODHandler *aodHandler = new AliAODHandler();
  const char* deltaAODfname="AliAOD.VertexingHF.root";
  if(createAOD) {
    aodHandler->SetOutputFileName("AliAOD.root");
  } else {
    aodHandler->SetFillAOD(kFALSE);
    aodHandler->SetOutputFileName(deltaAODfname);
    aodHandler->SetCreateNonStandardAOD();
  }
  mgr->SetOutputEventHandler(aodHandler);
  mgr->RegisterExtraFile(deltaAODfname);

  if(!inputAOD && createAOD) {
    // MC Truth
    AliMCEventHandler* mcHandler = new AliMCEventHandler();
    if(writeKineToAOD) mgr->SetMCtruthEventHandler(mcHandler);
    AliAnalysisTaskMCParticleFilter *kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Filter");
    if(writeKineToAOD) mgr->AddTask(kinefilter);
    // Barrel Tracks
    AliAnalysisTaskESDfilter *filter = new AliAnalysisTaskESDfilter("Filter");
    mgr->AddTask(filter);

    AliESDtrackCuts* esdTrackCutsHF = new AliESDtrackCuts("AliESDtrackCuts", "Heavy flavour");
    esdTrackCutsHF->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);

    AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
    trackFilter->AddCuts(esdTrackCutsHF);

    filter->SetTrackFilter(trackFilter);

    // Pipelining
    mgr->ConnectInput(filter,0,mgr->GetCommonInputContainer());
    mgr->ConnectOutput(filter,0,mgr->GetCommonOutputContainer());
    if(writeKineToAOD) {
      mgr->ConnectInput(kinefilter,0,mgr->GetCommonInputContainer());
      mgr->ConnectOutput(kinefilter,0,mgr->GetCommonOutputContainer());
    }

  }

  // Vertexing analysis task
  gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/macros/AddTaskVertexingHF.C");
  AliAnalysisTaskSEVertexingHF *hfTask = AddTaskVertexingHF(deltaAODfname);

  //
  // Run the analysis
  //
  printf("CHAIN HAS %d ENTRIES\n",(Int_t)chain->GetEntries());
  if(!mgr->InitAnalysis()) return;

  mgr->PrintStatus();

  TStopwatch watch;
  watch.Start();
  mgr->StartAnalysis(mode.Data(),chain);
  watch.Stop();
  watch.Print();

  return;
}
<commit_msg>Changed default settings<commit_after>void AliAnalysisTaskSEVertexingHFTest()
{
  //
  // Test macro for the AliAnalysisTaskSE for heavy-flavour vertexing
  // A.Dainese, andrea.dainese@lnl.infn.it
  //

  Bool_t inputAOD=kFALSE; // otherwise, ESD
  Bool_t createAOD=kTRUE; // kTRUE: create AOD and use it as input to vertexing
                          // kFALSE: use ESD as input to vertexing
  Bool_t writeKineToAOD = kFALSE;
  TString mode="local"; // otherwise, "grid"
  Bool_t useParFiles=kFALSE;

  gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/macros/LoadLibraries.C");
  LoadLibraries(useParFiles);

  TChain *chain = 0;

  if(mode=="local") {
    // Local files
    TString treeName,fileName;
    if(inputAOD) {
      treeName="aodTree";
      fileName="AliAOD.root";
    } else {
      treeName="esdTree";
      fileName="AliESDs.root";
    }
    chain = new TChain(treeName.Data());
    chain->Add(fileName.Data());

  } else if (mode=="grid") {
    //Fetch files with AliEn :
    const char *collectionfile = "Collection.xml";
    TGrid::Connect("alien://") ;
    TAlienCollection *coll   = TAlienCollection::Open(collectionfile);
    if(inputAOD) { // input AOD
      chain = new TChain("aodTree");
      while(coll->Next()) chain->Add(coll->GetTURL(""));
    } else { // input ESD
      //Create an AliRunTagCuts and an AliEventTagCuts Object and impose some selection criteria
      AliRunTagCuts      *runCuts   = new AliRunTagCuts();
      AliEventTagCuts    *eventCuts = new AliEventTagCuts();
      AliLHCTagCuts      *lhcCuts   = new AliLHCTagCuts();
      AliDetectorTagCuts *detCuts   = new AliDetectorTagCuts();
      eventCuts->SetMultiplicityRange(0,20000);
      //Create an AliTagAnalysis Object and chain the tags
      AliTagAnalysis   *tagAna = new AliTagAnalysis();
      tagAna->SetType("ESD");
      TGridResult      *tagResult = coll->GetGridResult("",0,0);
      tagResult->Print();
      tagAna->ChainGridTags(tagResult);
      //Create a new esd chain and assign the chain that is returned by querying the tags
      chain = tagAna->QueryTags(runCuts,lhcCuts,detCuts,eventCuts);
    }
  } else {
    printf("ERROR: mode has to be \"local\" or \"grid\" \n");
    return;
  }

  // Create the analysis manager
  AliAnalysisManager *mgr  = new AliAnalysisManager("My Manager","My Manager");
  mgr->SetDebugLevel(10);

  // Input Handler
  AliInputEventHandler *inputHandler = 0;
  if(inputAOD) {
    inputHandler = new AliAODInputHandler();
  } else {
    inputHandler = new AliESDInputHandler();
  }
  mgr->SetInputEventHandler(inputHandler);

  // Output
  AliAODHandler *aodHandler = new AliAODHandler();
  const char* deltaAODfname="AliAOD.VertexingHF.root";
  if(createAOD) {
    aodHandler->SetOutputFileName("AliAOD.root");
  } else {
    aodHandler->SetFillAOD(kFALSE);
    aodHandler->SetOutputFileName(deltaAODfname);
    aodHandler->SetCreateNonStandardAOD();
  }
  mgr->SetOutputEventHandler(aodHandler);
  mgr->RegisterExtraFile(deltaAODfname);

  if(!inputAOD && createAOD) {
    // MC Truth
    AliMCEventHandler* mcHandler = new AliMCEventHandler();
    if(writeKineToAOD) mgr->SetMCtruthEventHandler(mcHandler);
    AliAnalysisTaskMCParticleFilter *kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Filter");
    if(writeKineToAOD) mgr->AddTask(kinefilter);
    // Barrel Tracks
    AliAnalysisTaskESDfilter *filter = new AliAnalysisTaskESDfilter("Filter");
    mgr->AddTask(filter);

    AliESDtrackCuts* esdTrackCutsHF = new AliESDtrackCuts("AliESDtrackCuts", "Heavy flavour");
    esdTrackCutsHF->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);

    AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
    trackFilter->AddCuts(esdTrackCutsHF);

    filter->SetTrackFilter(trackFilter);

    // Pipelining
    mgr->ConnectInput(filter,0,mgr->GetCommonInputContainer());
    mgr->ConnectOutput(filter,0,mgr->GetCommonOutputContainer());
    if(writeKineToAOD) {
      mgr->ConnectInput(kinefilter,0,mgr->GetCommonInputContainer());
      mgr->ConnectOutput(kinefilter,0,mgr->GetCommonOutputContainer());
    }

  }

  // Vertexing analysis task
  gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/macros/AddTaskVertexingHF.C");
  AliAnalysisTaskSEVertexingHF *hfTask = AddTaskVertexingHF(deltaAODfname);

  //
  // Run the analysis
  //
  printf("CHAIN HAS %d ENTRIES\n",(Int_t)chain->GetEntries());
  if(!mgr->InitAnalysis()) return;

  mgr->PrintStatus();

  TStopwatch watch;
  watch.Start();
  mgr->StartAnalysis(mode.Data(),chain);
  watch.Stop();
  watch.Print();

  return;
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_posh/popo/rpc_header.hpp"

#include "iceoryx_posh/testing/mocks/chunk_mock.hpp"
#include "test.hpp"

namespace
{
using namespace ::testing;
using namespace iox::popo;

class RpcBaseHeaderAccess : public RpcBaseHeader
{
  public:
    using RpcBaseHeader::m_clientQueueUniquePortId;
    using RpcBaseHeader::m_lastKnownClientQueueIndex;
};

class RpcBaseHeader_test : public Test
{
  public:
    void SetUp() override
    {
    }

    void TearDown() override
    {
    }

    ChunkMock<bool, RpcBaseHeader> chunk;
    RpcBaseHeader* sut{new (chunk.userHeader())
                           RpcBaseHeader(iox::UniquePortId(), 73, 37, RpcBaseHeader::RPC_HEADER_VERSION)};
};

void checkRpcBaseHeader(const RpcBaseHeaderAccess* sut,
                        const iox::UniquePortId& clientQueueUniquePortId,
                        const uint32_t lastKnownClientQueueIndex,
                        const int64_t sequenceId,
                        const uint8_t rpcHeaderVersion = RpcBaseHeader::RPC_HEADER_VERSION)
{
    EXPECT_THAT(sut->getRpcHeaderVersion(), rpcHeaderVersion);
    EXPECT_THAT(sut->m_clientQueueUniquePortId, Eq(clientQueueUniquePortId));
    EXPECT_THAT(sut->m_lastKnownClientQueueIndex, lastKnownClientQueueIndex);
    EXPECT_THAT(sut->getSequenceId(), Eq(sequenceId));
}

TEST_F(RpcBaseHeader_test, ConstructorWorks)
{
    const iox::UniquePortId clientQueueUniquePortId;
    constexpr uint32_t LAST_KNOWN_CLIENT_QUEUE_INDEX{13};
    constexpr int64_t SEQUENCE_ID{42};
    constexpr uint8_t RPC_HEADER_VERSION{222};

    ChunkMock<bool, RpcBaseHeader> chunk;
    new (chunk.userHeader())
        RpcBaseHeader(clientQueueUniquePortId, LAST_KNOWN_CLIENT_QUEUE_INDEX, SEQUENCE_ID, RPC_HEADER_VERSION);

    checkRpcBaseHeader(static_cast<RpcBaseHeaderAccess*>(chunk.userHeader()),
                       clientQueueUniquePortId,
                       LAST_KNOWN_CLIENT_QUEUE_INDEX,
                       SEQUENCE_ID,
                       RPC_HEADER_VERSION);
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionFromNonConstContextWorks)
{
    EXPECT_THAT(static_cast<RpcBaseHeader*>(sut)->getChunkHeader(), Eq(chunk.chunkHeader()));
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionFromConstContextWorks)
{
    EXPECT_THAT(static_cast<const RpcBaseHeader*>(sut)->getChunkHeader(), Eq(chunk.chunkHeader()));
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionCalledFromNonConstContextReturnsNonConstType)
{
    auto isNonConstReturn =
        std::is_same<decltype(std::declval<RpcBaseHeader>().getChunkHeader()), iox::mepoo::ChunkHeader*>::value;
    EXPECT_TRUE(isNonConstReturn);
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionCalledFromConstContextReturnsConstType)
{
    auto isConstReturn = std::is_same<decltype(std::declval<const RpcBaseHeader>().getChunkHeader()),
                                      const iox::mepoo::ChunkHeader*>::value;
    EXPECT_TRUE(isConstReturn);
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionFromNonConstContextWorks)
{
    EXPECT_THAT(static_cast<RpcBaseHeader*>(sut)->getUserPayload(), Eq(chunk.chunkHeader()->userPayload()));
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionFromConstContextWorks)
{
    EXPECT_THAT(static_cast<const RpcBaseHeader*>(sut)->getUserPayload(), Eq(chunk.chunkHeader()->userPayload()));
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionCalledFromNonConstContextReturnsNonConstType)
{
    auto isNonConstReturn = std::is_same<decltype(std::declval<RpcBaseHeader>().getUserPayload()), void*>::value;
    EXPECT_TRUE(isNonConstReturn);
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionCalledFromConstContextReturnsConstType)
{
    auto isConstReturn =
        std::is_same<decltype(std::declval<const RpcBaseHeader>().getUserPayload()), const void*>::value;
    EXPECT_TRUE(isConstReturn);
}

} // namespace
<commit_msg>iox-#27 Add test for RequestHeader<commit_after>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_posh/popo/rpc_header.hpp"

#include "iceoryx_posh/testing/mocks/chunk_mock.hpp"
#include "test.hpp"

namespace
{
using namespace ::testing;
using namespace iox::popo;

class RpcBaseHeaderAccess : public RpcBaseHeader
{
  public:
    using RpcBaseHeader::m_clientQueueUniquePortId;
    using RpcBaseHeader::m_lastKnownClientQueueIndex;
};

class RpcBaseHeader_test : public Test
{
  public:
    void SetUp() override
    {
    }

    void TearDown() override
    {
    }

    ChunkMock<bool, RpcBaseHeader> chunk;
    RpcBaseHeader* sut{new (chunk.userHeader())
                           RpcBaseHeader(iox::UniquePortId(), 73, 37, RpcBaseHeader::RPC_HEADER_VERSION)};
};

void checkRpcBaseHeader(const RpcBaseHeaderAccess* sut,
                        const iox::UniquePortId& clientQueueUniquePortId,
                        const uint32_t lastKnownClientQueueIndex,
                        const int64_t sequenceId,
                        const uint8_t rpcHeaderVersion = RpcBaseHeader::RPC_HEADER_VERSION)
{
    EXPECT_THAT(sut->getRpcHeaderVersion(), rpcHeaderVersion);
    EXPECT_THAT(sut->m_clientQueueUniquePortId, Eq(clientQueueUniquePortId));
    EXPECT_THAT(sut->m_lastKnownClientQueueIndex, lastKnownClientQueueIndex);
    EXPECT_THAT(sut->getSequenceId(), Eq(sequenceId));
}

TEST_F(RpcBaseHeader_test, ConstructorWorks)
{
    const iox::UniquePortId clientQueueUniquePortId;
    constexpr uint32_t LAST_KNOWN_CLIENT_QUEUE_INDEX{13};
    constexpr int64_t SEQUENCE_ID{42};
    constexpr uint8_t RPC_HEADER_VERSION{222};

    ChunkMock<bool, RpcBaseHeader> chunk;
    new (chunk.userHeader())
        RpcBaseHeader(clientQueueUniquePortId, LAST_KNOWN_CLIENT_QUEUE_INDEX, SEQUENCE_ID, RPC_HEADER_VERSION);

    checkRpcBaseHeader(static_cast<RpcBaseHeaderAccess*>(chunk.userHeader()),
                       clientQueueUniquePortId,
                       LAST_KNOWN_CLIENT_QUEUE_INDEX,
                       SEQUENCE_ID,
                       RPC_HEADER_VERSION);
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionFromNonConstContextWorks)
{
    EXPECT_THAT(static_cast<RpcBaseHeader*>(sut)->getChunkHeader(), Eq(chunk.chunkHeader()));
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionFromConstContextWorks)
{
    EXPECT_THAT(static_cast<const RpcBaseHeader*>(sut)->getChunkHeader(), Eq(chunk.chunkHeader()));
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionCalledFromNonConstContextReturnsNonConstType)
{
    auto isNonConstReturn =
        std::is_same<decltype(std::declval<RpcBaseHeader>().getChunkHeader()), iox::mepoo::ChunkHeader*>::value;
    EXPECT_TRUE(isNonConstReturn);
}

TEST_F(RpcBaseHeader_test, GetChunkHeaderFunctionCalledFromConstContextReturnsConstType)
{
    auto isConstReturn = std::is_same<decltype(std::declval<const RpcBaseHeader>().getChunkHeader()),
                                      const iox::mepoo::ChunkHeader*>::value;
    EXPECT_TRUE(isConstReturn);
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionFromNonConstContextWorks)
{
    EXPECT_THAT(static_cast<RpcBaseHeader*>(sut)->getUserPayload(), Eq(chunk.chunkHeader()->userPayload()));
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionFromConstContextWorks)
{
    EXPECT_THAT(static_cast<const RpcBaseHeader*>(sut)->getUserPayload(), Eq(chunk.chunkHeader()->userPayload()));
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionCalledFromNonConstContextReturnsNonConstType)
{
    auto isNonConstReturn = std::is_same<decltype(std::declval<RpcBaseHeader>().getUserPayload()), void*>::value;
    EXPECT_TRUE(isNonConstReturn);
}

TEST_F(RpcBaseHeader_test, GetUserPayloadFunctionCalledFromConstContextReturnsConstType)
{
    auto isConstReturn =
        std::is_same<decltype(std::declval<const RpcBaseHeader>().getUserPayload()), const void*>::value;
    EXPECT_TRUE(isConstReturn);
}

class RequestHeader_test : public Test
{
  public:
    void SetUp() override
    {
    }

    void TearDown() override
    {
    }

    ChunkMock<bool, RpcBaseHeader> chunk;
    RequestHeader* sut{new (chunk.userHeader()) RequestHeader(iox::UniquePortId(), 73)};
};

TEST_F(RequestHeader_test, ConstructorWorks)
{
    const iox::UniquePortId clientQueueUniquePortId;
    constexpr uint32_t LAST_KNOWN_CLIENT_QUEUE_INDEX{13};
    constexpr int64_t EXPECTED_SEQUENCE_ID{0};
    constexpr uint8_t EXPECTED_RPC_HEADER_VERSION{RpcBaseHeader::RPC_HEADER_VERSION};

    ChunkMock<bool, RpcBaseHeader> chunk;
    auto requestHeader = new (chunk.userHeader()) RequestHeader(clientQueueUniquePortId, LAST_KNOWN_CLIENT_QUEUE_INDEX);

    checkRpcBaseHeader(static_cast<RpcBaseHeaderAccess*>(chunk.userHeader()),
                       clientQueueUniquePortId,
                       LAST_KNOWN_CLIENT_QUEUE_INDEX,
                       EXPECTED_SEQUENCE_ID,
                       EXPECTED_RPC_HEADER_VERSION);

    EXPECT_THAT(requestHeader->getFireAndForget(), Eq(false));
}

TEST_F(RequestHeader_test, SetSequenceIdWorks)
{
    constexpr int64_t SEQUENCE_ID{666};

    sut->setSequenceId(SEQUENCE_ID);

    EXPECT_THAT(sut->getSequenceId(), Eq(SEQUENCE_ID));
}

TEST_F(RequestHeader_test, SetFireAndForgetWorks)
{
    sut->setFireAndForget();

    EXPECT_THAT(sut->getFireAndForget(), Eq(true));
}

} // namespace
<|endoftext|>


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

#include <assert.h>
#include <sys/socket.h>

#include "xapiand.h"
#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = -1;

BaseClient::BaseClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: server(server_),
	  iterator(server->attach_client(this)),
	  io_read(*loop),
	  io_write(*loop),
	  async_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  thread_pool(thread_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	inc_ref();

	pthread_mutexattr_init(&qmtx_attr);
	pthread_mutexattr_settype(&qmtx_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&qmtx, &qmtx_attr);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = ++XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	async_write.set<BaseClient, &BaseClient::async_write_cb>(this);
	async_write.start();

	io_read.set<BaseClient, &BaseClient::io_cb>(this);
	io_read.start(sock, ev::READ);

	io_write.set<BaseClient, &BaseClient::io_cb>(this);
	io_write.set(sock, ev::WRITE);

	LOG_OBJ(this, "CREATED CLIENT! (%d clients)\n", total_clients);
}

BaseClient::~BaseClient()
{
	destroy();

	while(!write_queue.empty()) {
		Buffer *buffer;
		if (write_queue.pop(buffer, 0)) {
			delete buffer;
		}
	}

	server->detach_client(this);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = --XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	pthread_mutex_destroy(&qmtx);
	pthread_mutexattr_destroy(&qmtx_attr);

	LOG_OBJ(this, "DELETED CLIENT! (%d clients left)\n", total_clients);
	assert(total_clients >= 0);
}

void BaseClient::destroy()
{
	close();

	pthread_mutex_lock(&qmtx);
	if (sock == -1) {
		pthread_mutex_unlock(&qmtx);
		return;
	}

	// Stop and free watcher if client socket is closing
	io_read.stop();
	io_write.stop();

	::close(sock);
	sock = -1;
	pthread_mutex_unlock(&qmtx);

	LOG_OBJ(this, "DESTROYED CLIENT!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED CLIENT!\n");
}

void BaseClient::io_update() {
	if (sock != -1) {
		if (write_queue.empty()) {
			if (closed) {
				destroy();
			} else {
				io_write.stop();
			}
		} else {
			io_write.start();
		}
	}

	if (sock == -1) {
		rel_ref();
	}

}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	LOG_EV(this, "%s (sock=%d) %x\n", (revents & EV_WRITE & EV_READ) ? "IO_CB" : (revents & EV_WRITE) ? "WRITE_CB" : (revents & EV_READ) ? "READ_CB" : "IO_CB", sock, revents);

	if (sock == -1) {
		return;
	}

	assert(sock == watcher.fd);

	if (sock != -1 && revents & EV_WRITE) {
		write_cb();
	}

	if (sock != -1 && revents & EV_READ) {
		read_cb();
	}

	io_update();
}

void BaseClient::write_cb()
{
	if (!write_queue.empty()) {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN_WIRE(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(sock, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				if(write_queue.pop(buffer)) {
					delete buffer;
				}
			}
		}
	}
}

void BaseClient::read_cb()
{
	char buf[1024];

	ssize_t received = ::read(sock, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN_WIRE(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
	memset(&buf, 0, sizeof(buf));
}

void BaseClient::async_write_cb(ev::async &watcher, int revents)
{
	io_update();
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN_WIRE(this, "(sock=%d) <ENQUEUE> '%s'\n", sock, repr(buf, buf_size).c_str());

	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	async_write.send();
}

void BaseClient::shutdown()
{
	if (server->manager->shutdown_now) {
		LOG_EV(this, "Signaled destroy!!\n");
		destroy();
		rel_ref();
	}
}
<commit_msg>Don't use memset.<commit_after>/*
 * Copyright deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <assert.h>
#include <sys/socket.h>

#include "xapiand.h"
#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = -1;

BaseClient::BaseClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: server(server_),
	  iterator(server->attach_client(this)),
	  io_read(*loop),
	  io_write(*loop),
	  async_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  thread_pool(thread_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	inc_ref();

	pthread_mutexattr_init(&qmtx_attr);
	pthread_mutexattr_settype(&qmtx_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&qmtx, &qmtx_attr);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = ++XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	async_write.set<BaseClient, &BaseClient::async_write_cb>(this);
	async_write.start();

	io_read.set<BaseClient, &BaseClient::io_cb>(this);
	io_read.start(sock, ev::READ);

	io_write.set<BaseClient, &BaseClient::io_cb>(this);
	io_write.set(sock, ev::WRITE);

	LOG_OBJ(this, "CREATED CLIENT! (%d clients)\n", total_clients);
}

BaseClient::~BaseClient()
{
	destroy();

	while(!write_queue.empty()) {
		Buffer *buffer;
		if (write_queue.pop(buffer, 0)) {
			delete buffer;
		}
	}

	server->detach_client(this);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = --XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	pthread_mutex_destroy(&qmtx);
	pthread_mutexattr_destroy(&qmtx_attr);

	LOG_OBJ(this, "DELETED CLIENT! (%d clients left)\n", total_clients);
	assert(total_clients >= 0);
}

void BaseClient::destroy()
{
	close();

	pthread_mutex_lock(&qmtx);
	if (sock == -1) {
		pthread_mutex_unlock(&qmtx);
		return;
	}

	// Stop and free watcher if client socket is closing
	io_read.stop();
	io_write.stop();

	::close(sock);
	sock = -1;
	pthread_mutex_unlock(&qmtx);

	LOG_OBJ(this, "DESTROYED CLIENT!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED CLIENT!\n");
}

void BaseClient::io_update() {
	if (sock != -1) {
		if (write_queue.empty()) {
			if (closed) {
				destroy();
			} else {
				io_write.stop();
			}
		} else {
			io_write.start();
		}
	}

	if (sock == -1) {
		rel_ref();
	}

}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	LOG_EV(this, "%s (sock=%d) %x\n", (revents & EV_WRITE & EV_READ) ? "IO_CB" : (revents & EV_WRITE) ? "WRITE_CB" : (revents & EV_READ) ? "READ_CB" : "IO_CB", sock, revents);

	if (sock == -1) {
		return;
	}

	assert(sock == watcher.fd);

	if (sock != -1 && revents & EV_WRITE) {
		write_cb();
	}

	if (sock != -1 && revents & EV_READ) {
		read_cb();
	}

	io_update();
}

void BaseClient::write_cb()
{
	if (!write_queue.empty()) {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN_WIRE(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(sock, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				if(write_queue.pop(buffer)) {
					delete buffer;
				}
			}
		}
	}
}

void BaseClient::read_cb()
{
	char buf[1024];

	ssize_t received = ::read(sock, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN_WIRE(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
}

void BaseClient::async_write_cb(ev::async &watcher, int revents)
{
	io_update();
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN_WIRE(this, "(sock=%d) <ENQUEUE> '%s'\n", sock, repr(buf, buf_size).c_str());

	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	async_write.send();
}

void BaseClient::shutdown()
{
	if (server->manager->shutdown_now) {
		LOG_EV(this, "Signaled destroy!!\n");
		destroy();
		rel_ref();
	}
}
<|endoftext|>