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

// actually this workaround should be in presys.h!
//#define UINT64 USE_WIN_UINT64
//#define INT64 USE_WIN_INT64
//#define UINT32 USE_WIN_UINT32
//#define INT32 USE_WIN_INT32

//#include <tools/presys.h>
#include "embeddoc.hxx"
//#include <tools/postsys.h>

//#undef UINT64
//#undef INT64
//#undef UINT32
//#undef INT32

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif

#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif

#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif

#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

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

//===============================================================================
// EmbedDocument_Impl
//===============================================================================

sal_uInt64 EmbedDocument_Impl::getMetaFileHandle_Impl( sal_Bool isEnhMeta )
{
    sal_uInt64 pResult = NULL;

    uno::Reference< datatransfer::XTransferable > xTransferable( m_pDocHolder->GetDocument(), uno::UNO_QUERY );
    if ( xTransferable.is() )
    {
        uno::Sequence< sal_Int8 > aMetaBuffer;
        datatransfer::DataFlavor aFlavor;

        if ( isEnhMeta )
        {
            aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                                "application/x-openoffice;windows_formatname=\"Image EMF\"" ) );
            aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
        }
        else
        {
            aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                                "application/x-openoffice;windows_formatname=\"Image WMF\"" ) );
            aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows GDIMetaFile" ) );
        }

        aFlavor.DataType = getCppuType( (const sal_uInt64*) 0 );

        uno::Any aAny = xTransferable->getTransferData( aFlavor );
        aAny >>= pResult;
    }

    return pResult;
}

//-------------------------------------------------------------------------------
// IDataObject

STDMETHODIMP EmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
{
    if ( !pFormatetc )
        return DV_E_FORMATETC;

    if ( !pMedium )
        return STG_E_MEDIUMFULL;

    if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
      || pFormatetc->dwAspect == DVASPECT_ICON
      || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
        return DV_E_DVASPECT;

    if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
    {
        if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
            return DV_E_TYMED;

        HENHMETAFILE hMeta = reinterpret_cast<HENHMETAFILE>( getMetaFileHandle_Impl( sal_True ) );

        if ( hMeta )
        {
            pMedium->tymed = TYMED_ENHMF;
            pMedium->hEnhMetaFile = hMeta;
            pMedium->pUnkForRelease = NULL;

            return S_OK;
        }

        return STG_E_MEDIUMFULL;
    }
    else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
    {
          if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
            return DV_E_TYMED;

        HGLOBAL hMeta = reinterpret_cast<HGLOBAL>( getMetaFileHandle_Impl( sal_False ) );

        if ( hMeta )
        {
            pMedium->tymed = TYMED_MFPICT;
            pMedium->hMetaFilePict = hMeta;
            pMedium->pUnkForRelease = NULL;
        }

        return STG_E_MEDIUMFULL;
    }
    else
    {
        CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
        if ( pFormatetc->cfFormat == cf_embSource )
        {
            if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
                return DV_E_TYMED;

            CComPtr< IStorage > pNewStg;
            HRESULT hr = StgCreateDocfile( NULL, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, 0, &pNewStg );
            if ( FAILED( hr ) || !pNewStg ) return STG_E_MEDIUMFULL;

            hr = SaveTo_Impl( pNewStg );
            if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;

            pMedium->tymed = TYMED_ISTORAGE;
            pMedium->pstg = pNewStg;
            pMedium->pstg->AddRef();
            pMedium->pUnkForRelease = ( IUnknown* )pNewStg;

            return S_OK;
        }
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
{
    if ( !pFormatetc )
        return DV_E_FORMATETC;

    if ( !pMedium )
        return STG_E_MEDIUMFULL;

    if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
      || pFormatetc->dwAspect == DVASPECT_ICON
      || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
        return DV_E_DVASPECT;

    CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
    if ( pFormatetc->cfFormat == cf_embSource )
    {
        if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
            return DV_E_TYMED;

        if ( !pMedium->pstg ) return STG_E_MEDIUMFULL;

        HRESULT hr = SaveTo_Impl( pMedium->pstg );
        if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;

        pMedium->tymed = TYMED_ISTORAGE;
        pMedium->pUnkForRelease = NULL;

        return S_OK;
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )
{
    if ( pFormatetc )
    {
        if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
          || pFormatetc->dwAspect == DVASPECT_ICON
          || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
            return DV_E_DVASPECT;

        if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
        {
            if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
                return DV_E_TYMED;

            return S_OK;
        }
        else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
        {
              if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
                return DV_E_TYMED;

            return S_OK;
        }
        else
        {
            CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
            if ( pFormatetc->cfFormat == cf_embSource )
            {
                if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
                    return DV_E_TYMED;

                return S_OK;
            }
        }
    }

    return DV_E_FORMATETC;

}

STDMETHODIMP EmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )
{
    if ( !pFormatetcIn || !pFormatetcOut )
        return DV_E_FORMATETC;

    pFormatetcOut->ptd = NULL;
    pFormatetcOut->cfFormat = pFormatetcIn->cfFormat;
    pFormatetcOut->dwAspect = DVASPECT_CONTENT;

    if ( pFormatetcIn->cfFormat == CF_ENHMETAFILE )
    {
        pFormatetcOut->tymed = TYMED_ENHMF;
        return S_OK;
    }
    else if ( pFormatetcIn->cfFormat == CF_METAFILEPICT )
    {
          pFormatetcOut->tymed = TYMED_MFPICT;
        return S_OK;
    }
    else
    {
        CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
        if ( pFormatetcIn->cfFormat == cf_embSource )
        {
            pFormatetcOut->tymed = TYMED_ISTORAGE;
            return S_OK;
        }
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease )
{
    return E_NOTIMPL;
}

STDMETHODIMP EmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc )
{
    if ( dwDirection == DATADIR_GET )
        return OLE_S_USEREG;

    return E_NOTIMPL;
}

STDMETHODIMP EmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->Advise( (IDataObject*)this, pFormatetc, advf, pAdvSink, pdwConnection );
}

STDMETHODIMP EmbedDocument_Impl::DUnadvise( DWORD dwConnection )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->Unadvise( dwConnection );
}

STDMETHODIMP EmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->EnumAdvise( ppenumAdvise );
}

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

// actually this workaround should be in presys.h!
//#define UINT64 USE_WIN_UINT64
//#define INT64 USE_WIN_INT64
//#define UINT32 USE_WIN_UINT32
//#define INT32 USE_WIN_INT32

//#include <tools/presys.h>
#include "embeddoc.hxx"
//#include <tools/postsys.h>

//#undef UINT64
//#undef INT64
//#undef UINT32
//#undef INT32

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif

#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif

#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif

#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

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

//===============================================================================
// EmbedDocument_Impl
//===============================================================================

sal_uInt64 EmbedDocument_Impl::getMetaFileHandle_Impl( sal_Bool isEnhMeta )
{
    sal_uInt64 pResult = NULL;

    uno::Reference< datatransfer::XTransferable > xTransferable( m_pDocHolder->GetDocument(), uno::UNO_QUERY );
    if ( xTransferable.is() )
    {
        uno::Sequence< sal_Int8 > aMetaBuffer;
        datatransfer::DataFlavor aFlavor;

        if ( isEnhMeta )
        {
            aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                                "application/x-openoffice;windows_formatname=\"Image EMF\"" ) );
            aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
        }
        else
        {
            aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                                "application/x-openoffice;windows_formatname=\"Image WMF\"" ) );
            aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows GDIMetaFile" ) );
        }

        aFlavor.DataType = getCppuType( (const sal_uInt64*) 0 );

        uno::Any aAny = xTransferable->getTransferData( aFlavor );
        aAny >>= pResult;
    }

    return pResult;
}

//-------------------------------------------------------------------------------
// IDataObject

STDMETHODIMP EmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
{
    if ( !pFormatetc )
        return DV_E_FORMATETC;

    if ( !pMedium )
        return STG_E_MEDIUMFULL;

    if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
      || pFormatetc->dwAspect == DVASPECT_ICON
      || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
        return DV_E_DVASPECT;

    if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
    {
        if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
            return DV_E_TYMED;

        HENHMETAFILE hMeta = reinterpret_cast<HENHMETAFILE>( getMetaFileHandle_Impl( sal_True ) );

        if ( hMeta )
        {
            pMedium->tymed = TYMED_ENHMF;
            pMedium->hEnhMetaFile = hMeta;
            pMedium->pUnkForRelease = NULL;

            return S_OK;
        }

        return STG_E_MEDIUMFULL;
    }
    else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
    {
          if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
            return DV_E_TYMED;

        HGLOBAL hMeta = reinterpret_cast<HGLOBAL>( getMetaFileHandle_Impl( sal_False ) );

        if ( hMeta )
        {
            pMedium->tymed = TYMED_MFPICT;
            pMedium->hMetaFilePict = hMeta;
            pMedium->pUnkForRelease = NULL;

            return S_OK;
        }

        return STG_E_MEDIUMFULL;
    }
    else
    {
        CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
        CLIPFORMAT cf_embObj = RegisterClipboardFormatA( "Embedded Object" );
        if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
        {
            if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
                return DV_E_TYMED;

            CComPtr< IStorage > pNewStg;
            HRESULT hr = StgCreateDocfile( NULL, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, 0, &pNewStg );
            if ( FAILED( hr ) || !pNewStg ) return STG_E_MEDIUMFULL;

            hr = SaveTo_Impl( pNewStg );
            if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;

            pMedium->tymed = TYMED_ISTORAGE;
            pMedium->pstg = pNewStg;
            pMedium->pstg->AddRef();
            pMedium->pUnkForRelease = ( IUnknown* )pNewStg;

            return S_OK;
        }
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
{
    if ( !pFormatetc )
        return DV_E_FORMATETC;

    if ( !pMedium )
        return STG_E_MEDIUMFULL;

    if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
      || pFormatetc->dwAspect == DVASPECT_ICON
      || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
        return DV_E_DVASPECT;

    CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
    CLIPFORMAT cf_embObj = RegisterClipboardFormatA( "Embedded Object" );

    if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
    {
        if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
            return DV_E_TYMED;

        if ( !pMedium->pstg ) return STG_E_MEDIUMFULL;

        HRESULT hr = SaveTo_Impl( pMedium->pstg );
        if ( FAILED( hr ) ) return STG_E_MEDIUMFULL;

        pMedium->tymed = TYMED_ISTORAGE;
        pMedium->pUnkForRelease = NULL;

        return S_OK;
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )
{
    if ( pFormatetc )
    {
        if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL
          || pFormatetc->dwAspect == DVASPECT_ICON
          || pFormatetc->dwAspect == DVASPECT_DOCPRINT )
            return DV_E_DVASPECT;

        if ( pFormatetc->cfFormat == CF_ENHMETAFILE )
        {
            if ( !( pFormatetc->tymed & TYMED_ENHMF ) )
                return DV_E_TYMED;

            return S_OK;
        }
        else if ( pFormatetc->cfFormat == CF_METAFILEPICT )
        {
              if ( !( pFormatetc->tymed & TYMED_MFPICT ) )
                return DV_E_TYMED;

            return S_OK;
        }
        else
        {
            CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
            CLIPFORMAT cf_embObj = RegisterClipboardFormatA( "Embedded Object" );
            if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj )
            {
                if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) )
                    return DV_E_TYMED;

                return S_OK;
            }
        }
    }

    return DV_E_FORMATETC;

}

STDMETHODIMP EmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )
{
    if ( !pFormatetcIn || !pFormatetcOut )
        return DV_E_FORMATETC;

    pFormatetcOut->ptd = NULL;
    pFormatetcOut->cfFormat = pFormatetcIn->cfFormat;
    pFormatetcOut->dwAspect = DVASPECT_CONTENT;

    if ( pFormatetcIn->cfFormat == CF_ENHMETAFILE )
    {
        pFormatetcOut->tymed = TYMED_ENHMF;
        return S_OK;
    }
    else if ( pFormatetcIn->cfFormat == CF_METAFILEPICT )
    {
          pFormatetcOut->tymed = TYMED_MFPICT;
        return S_OK;
    }
    else
    {
        CLIPFORMAT cf_embSource = RegisterClipboardFormatA( "Embed Source" );
        CLIPFORMAT cf_embObj = RegisterClipboardFormatA( "Embedded Object" );
        if ( pFormatetcIn->cfFormat == cf_embSource || pFormatetcIn->cfFormat == cf_embObj )
        {
            pFormatetcOut->tymed = TYMED_ISTORAGE;
            return S_OK;
        }
    }

    return DV_E_FORMATETC;
}

STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease )
{
    return E_NOTIMPL;
}

STDMETHODIMP EmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc )
{
    if ( dwDirection == DATADIR_GET )
        return OLE_S_USEREG;

    return E_NOTIMPL;
}

STDMETHODIMP EmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->Advise( (IDataObject*)this, pFormatetc, advf, pAdvSink, pdwConnection );
}

STDMETHODIMP EmbedDocument_Impl::DUnadvise( DWORD dwConnection )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->Unadvise( dwConnection );
}

STDMETHODIMP EmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise )
{
    if ( !m_pDAdviseHolder )
        if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder )
            return E_OUTOFMEMORY;

    return m_pDAdviseHolder->EnumAdvise( ppenumAdvise );
}

<|endoftext|>


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

#include "../../core/Setup.h"

#if OUZEL_COMPILE_OPENSL

#include <system_error>
#include "OSLAudioDevice.hpp"
#include "OSLErrorCategory.hpp"
#include "../../core/Engine.hpp"
#include "../../utils/Log.hpp"

namespace ouzel::audio::opensl
{
    namespace
    {
        const ErrorCategory errorCategory{};

        std::error_code makeErrorCode(SLresult e)
        {
            return std::error_code(static_cast<int>(e), errorCategory);
        }

        void playerCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context)
        {
            try
            {
                auto audioDevice = static_cast<AudioDevice*>(context);

                audioDevice->enqueue(bufferQueue);
            }
            catch (const std::exception& e)
            {
                logger.log(Log::Level::error) << e.what();
            }
        }

        constexpr SLuint32 getChannelMask(std::uint32_t channels)
        {
            switch (channels)
            {
                case 1: return SL_SPEAKER_FRONT_CENTER;
                case 2: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
                case 4: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT;
                case 6: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
                case 7: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
                case 8: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
                default:
                    throw std::runtime_error("Invalid channel count");
            }
        }
    }

    AudioDevice::AudioDevice(const Settings& settings,
                             const std::function<void(std::uint32_t frames,
                                                      std::uint32_t channels,
                                                      std::uint32_t sampleRate,
                                                      std::vector<float>& samples)>& initDataGetter):
        audio::AudioDevice(Driver::openSL, settings, initDataGetter)
    {
        constexpr SLuint32 engineMixIIDCount = 1;
        const auto engineMixIID = SL_IID_ENGINE;
        constexpr SLboolean engineMixReq = SL_BOOLEAN_TRUE;

        SLObjectItf engineObjectPointer;
        if (const auto result = slCreateEngine(&engineObjectPointer, 0, nullptr, engineMixIIDCount, &engineMixIID, &engineMixReq); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL engine object");

        engineObject = engineObjectPointer;

        if (const auto result = engineObject->Realize(engineObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL engine object");

        SLEngineCapabilitiesItf engineCapabilities;
        if (const auto result = engineObject->GetInterface(engineObject.get(), SL_IID_ENGINECAPABILITIES, &engineCapabilities); result != SL_RESULT_SUCCESS)
           throw std::system_error(makeErrorCode(result), "Failed to get OpenSL engine capabilities");

        SLint16 major;
        SLint16 minor;
        SLint16 step;
        if (const auto result = (*engineCapabilities)->QueryAPIVersion(engineCapabilities, &major, &minor, &step); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL version");

        apiMajorVersion = static_cast<std::uint16_t>(major);
        apiMinorVersion = static_cast<std::uint16_t>(minor);

        if (const auto result = engineObject->GetInterface(engineObject.get(), SL_IID_ENGINE, &engine); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL engine");

        SLObjectItf outputMixObjectPointer;
        if (const auto result = (*engine)->CreateOutputMix(engine, &outputMixObjectPointer, 0, nullptr, nullptr); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL output mix");

        outputMixObject = outputMixObjectPointer;

        if (const auto result = outputMixObject->Realize(outputMixObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL output mix");

        SLDataLocator_AndroidSimpleBufferQueue location = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

        SLDataFormat_PCM dataFormat;
        dataFormat.formatType = SL_DATAFORMAT_PCM;
        // TODO: get speaker count
        dataFormat.numChannels = channels;
        dataFormat.samplesPerSec = sampleRate * 1000; // mHz
        dataFormat.bitsPerSample = sizeof(std::int16_t) * 8;
        dataFormat.containerSize = dataFormat.bitsPerSample;
        dataFormat.channelMask = getChannelMask(channels);
        dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

        SLDataSource dataSource{&location, &dataFormat};
        SLDataLocator_OutputMix dataLocatorOut{SL_DATALOCATOR_OUTPUTMIX, outputMixObject.get()};
        SLDataSink dataSink{&dataLocatorOut, nullptr};
        constexpr SLuint32 playerIIDCount = 3;
        const SLInterfaceID playerIIDs[] = {SL_IID_BUFFERQUEUE, SL_IID_PLAY, SL_IID_VOLUME};
        constexpr SLboolean playerReqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};

        SLObjectItf playerObjectPointer;
        if (const auto result = (*engine)->CreateAudioPlayer(engine, &playerObjectPointer, &dataSource, &dataSink, playerIIDCount, playerIIDs, playerReqs); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL player object");

        playerObject = playerObjectPointer;

        sampleFormat = SampleFormat::signedInt16;

        if (const auto result = playerObject->Realize(playerObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL player object");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_PLAY, &player); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL player interface");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_BUFFERQUEUE, &bufferQueue); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL buffer queue interface");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_VOLUME, &playerVolume); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL volume interface");

        if (const auto result = (*bufferQueue)->Clear(bufferQueue); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to clear OpenSL buffer");

        if (const auto result = (*bufferQueue)->RegisterCallback(bufferQueue, playerCallback, this); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to register OpenSL buffer queue callback");
    }

    void AudioDevice::start()
    {
        getData(bufferSize / (channels * sizeof(std::int16_t)), data);

        if (const auto result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to enqueue OpenSL data");

        if (const auto result = (*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to play sound");
    }

    void AudioDevice::stop()
    {
        if (const auto result = (*player)->SetPlayState(player, SL_PLAYSTATE_STOPPED); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to stop sound");
    }

    void AudioDevice::enqueue(SLAndroidSimpleBufferQueueItf bufferQueue)
    {
        getData(bufferSize / (channels * sizeof(std::int16_t)), data);

        if (const auto result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to enqueue OpenSL data");
    }
}
#endif
<commit_msg>Make the capability interface optional for OpenSL ES engine because it is not supported on all devices<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#include "../../core/Setup.h"

#if OUZEL_COMPILE_OPENSL

#include <array>
#include <system_error>
#include "OSLAudioDevice.hpp"
#include "OSLErrorCategory.hpp"
#include "../../core/Engine.hpp"
#include "../../utils/Log.hpp"

namespace ouzel::audio::opensl
{
    namespace
    {
        const ErrorCategory errorCategory{};

        std::error_code makeErrorCode(SLresult e)
        {
            return std::error_code(static_cast<int>(e), errorCategory);
        }

        void playerCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context)
        {
            try
            {
                auto audioDevice = static_cast<AudioDevice*>(context);

                audioDevice->enqueue(bufferQueue);
            }
            catch (const std::exception& e)
            {
                logger.log(Log::Level::error) << e.what();
            }
        }

        constexpr SLuint32 getChannelMask(std::uint32_t channels)
        {
            switch (channels)
            {
                case 1: return SL_SPEAKER_FRONT_CENTER;
                case 2: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
                case 4: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT;
                case 6: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
                case 7: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
                case 8: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
                default:
                    throw std::runtime_error("Invalid channel count");
            }
        }
    }

    AudioDevice::AudioDevice(const Settings& settings,
                             const std::function<void(std::uint32_t frames,
                                                      std::uint32_t channels,
                                                      std::uint32_t sampleRate,
                                                      std::vector<float>& samples)>& initDataGetter):
        audio::AudioDevice(Driver::openSL, settings, initDataGetter)
    {
        const std::array engineInterfaces = { SL_IID_ENGINE, SL_IID_ENGINECAPABILITIES };
        constexpr std::array engineRequirements = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE };

        SLObjectItf engineObjectPointer;
        if (const auto result = slCreateEngine(&engineObjectPointer, 0, nullptr,
                                               static_cast<SLuint32>(engineInterfaces.size()),
                                               engineInterfaces.data(),
                                               engineRequirements.data()); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL engine object");

        engineObject = engineObjectPointer;

        if (const auto result = engineObject->Realize(engineObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL engine object");

        SLEngineCapabilitiesItf engineCapabilities;
        if (const auto result = engineObject->GetInterface(engineObject.get(), SL_IID_ENGINECAPABILITIES, &engineCapabilities); result == SL_RESULT_SUCCESS)
        {
            SLint16 major;
            SLint16 minor;
            SLint16 step;
            if (const auto result = (*engineCapabilities)->QueryAPIVersion(engineCapabilities, &major, &minor, &step); result != SL_RESULT_SUCCESS)
                throw std::system_error(makeErrorCode(result), "Failed to get OpenSL version");

            apiMajorVersion = static_cast<std::uint16_t>(major);
            apiMinorVersion = static_cast<std::uint16_t>(minor);
        }
        else
        {
            apiMajorVersion = 1;
            apiMinorVersion = 0;
        }

        if (const auto result = engineObject->GetInterface(engineObject.get(), SL_IID_ENGINE, &engine); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL engine");

        SLObjectItf outputMixObjectPointer;
        if (const auto result = (*engine)->CreateOutputMix(engine, &outputMixObjectPointer, 0, nullptr, nullptr); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL output mix");

        outputMixObject = outputMixObjectPointer;

        if (const auto result = outputMixObject->Realize(outputMixObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL output mix");

        SLDataLocator_AndroidSimpleBufferQueue location = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

        SLDataFormat_PCM dataFormat;
        dataFormat.formatType = SL_DATAFORMAT_PCM;
        // TODO: get speaker count
        dataFormat.numChannels = channels;
        dataFormat.samplesPerSec = sampleRate * 1000; // mHz
        dataFormat.bitsPerSample = sizeof(std::int16_t) * 8;
        dataFormat.containerSize = dataFormat.bitsPerSample;
        dataFormat.channelMask = getChannelMask(channels);
        dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

        SLDataSource dataSource{&location, &dataFormat};
        SLDataLocator_OutputMix dataLocatorOut{SL_DATALOCATOR_OUTPUTMIX, outputMixObject.get()};
        SLDataSink dataSink{&dataLocatorOut, nullptr};
        constexpr SLuint32 playerIIDCount = 3;
        const SLInterfaceID playerIIDs[] = {SL_IID_BUFFERQUEUE, SL_IID_PLAY, SL_IID_VOLUME};
        constexpr SLboolean playerReqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};

        SLObjectItf playerObjectPointer;
        if (const auto result = (*engine)->CreateAudioPlayer(engine, &playerObjectPointer, &dataSource, &dataSink, playerIIDCount, playerIIDs, playerReqs); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL player object");

        playerObject = playerObjectPointer;

        sampleFormat = SampleFormat::signedInt16;

        if (const auto result = playerObject->Realize(playerObject.get(), SL_BOOLEAN_FALSE); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to create OpenSL player object");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_PLAY, &player); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL player interface");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_BUFFERQUEUE, &bufferQueue); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL buffer queue interface");

        if (const auto result = playerObject->GetInterface(playerObject.get(), SL_IID_VOLUME, &playerVolume); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to get OpenSL volume interface");

        if (const auto result = (*bufferQueue)->Clear(bufferQueue); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to clear OpenSL buffer");

        if (const auto result = (*bufferQueue)->RegisterCallback(bufferQueue, playerCallback, this); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to register OpenSL buffer queue callback");
    }

    void AudioDevice::start()
    {
        getData(bufferSize / (channels * sizeof(std::int16_t)), data);

        if (const auto result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to enqueue OpenSL data");

        if (const auto result = (*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to play sound");
    }

    void AudioDevice::stop()
    {
        if (const auto result = (*player)->SetPlayState(player, SL_PLAYSTATE_STOPPED); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to stop sound");
    }

    void AudioDevice::enqueue(SLAndroidSimpleBufferQueueItf bufferQueue)
    {
        getData(bufferSize / (channels * sizeof(std::int16_t)), data);

        if (const auto result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()); result != SL_RESULT_SUCCESS)
            throw std::system_error(makeErrorCode(result), "Failed to enqueue OpenSL data");
    }
}
#endif
<|endoftext|>


<commit_before>/*
 * OneToManyProcessor.cpp
 */

#include "OneToManyProcessor.h"
#include "WebRtcConnection.h"
#include "rtp/RtpHeaders.h"

namespace erizo {
  DEFINE_LOGGER(OneToManyProcessor, "OneToManyProcessor");
  OneToManyProcessor::OneToManyProcessor() {
    ELOG_DEBUG ("OneToManyProcessor constructor");
    feedbackSink_ = NULL;
  }

  OneToManyProcessor::~OneToManyProcessor() {
    ELOG_DEBUG ("OneToManyProcessor destructor");
    this->closeAll();
  }

  int OneToManyProcessor::deliverAudioData_(char* buf, int len) {
 //   ELOG_DEBUG ("OneToManyProcessor deliverAudio");
    if (len <= 0)
      return 0;

    boost::unique_lock<boost::mutex> lock(myMonitor_);
    if(subscribers.empty())
      return 0;

    std::map<std::string, sink_ptr>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      (*it).second->deliverAudioData(buf, len);
    }

    return 0;
  }

  int OneToManyProcessor::deliverVideoData_(char* buf, int len) {
    if (len <= 0)
      return 0;
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(buf);
    if(head->isFeedback()){
      ELOG_WARN("Receiving Feedback in wrong path: %d", head->packettype);
      if (feedbackSink_!=NULL){
        head->ssrc = htonl(publisher->getVideoSourceSSRC());
        feedbackSink_->deliverFeedback(buf,len);
      }
      return 0;
    }
    boost::unique_lock<boost::mutex> lock(myMonitor_);
    if (subscribers.empty())
      return 0;

    std::map<std::string, sink_ptr>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if((*it).second != NULL) {
        (*it).second->deliverVideoData(buf, len);
      }
    }
    return 0;
  }

  void OneToManyProcessor::setPublisher(MediaSource* webRtcConn) {
    ELOG_DEBUG("Set Publisher");
    boost::mutex::scoped_lock lock(myMonitor_);
    this->publisher.reset(webRtcConn);
    feedbackSink_ = publisher->getFeedbackSink();
  }

  int OneToManyProcessor::deliverFeedback_(char* buf, int len){
    if (feedbackSink_ != NULL){
      feedbackSink_->deliverFeedback(buf,len);
    }
    return 0;
  }

  void OneToManyProcessor::addSubscriber(MediaSink* webRtcConn,
      const std::string& peerId) {
    ELOG_DEBUG("Adding subscriber");
    boost::mutex::scoped_lock lock(myMonitor_);
    ELOG_DEBUG("From %u, %u ", publisher->getAudioSourceSSRC() , publisher->getVideoSourceSSRC());
    webRtcConn->setAudioSinkSSRC(this->publisher->getAudioSourceSSRC());
    webRtcConn->setVideoSinkSSRC(this->publisher->getVideoSourceSSRC());
    ELOG_DEBUG("Subscribers ssrcs: Audio %u, video, %u from %u, %u ", webRtcConn->getAudioSinkSSRC(), webRtcConn->getVideoSinkSSRC(), this->publisher->getAudioSourceSSRC() , this->publisher->getVideoSourceSSRC());
    FeedbackSource* fbsource = webRtcConn->getFeedbackSource();

    if (fbsource!=NULL){
      ELOG_DEBUG("adding fbsource");
      fbsource->setFeedbackSink(this);
    }
    this->subscribers[peerId] = sink_ptr(webRtcConn);
  }

  void OneToManyProcessor::removeSubscriber(const std::string& peerId) {
    ELOG_DEBUG("Remove subscriber");
    boost::mutex::scoped_lock lock(myMonitor_);
    if (this->subscribers.find(peerId) != subscribers.end()) {
      this->subscribers.erase(peerId);
    }
  }

  void OneToManyProcessor::closeAll() {
    ELOG_DEBUG ("OneToManyProcessor closeAll");
    feedbackSink_ = NULL;
    publisher.reset();
    boost::unique_lock<boost::mutex> lock(myMonitor_);
    std::map<std::string, boost::shared_ptr<MediaSink> >::iterator it = subscribers.begin();
    while (it != subscribers.end()) {
      if ((*it).second != NULL) {
        FeedbackSource* fbsource = (*it).second->getFeedbackSource();
        if (fbsource!=NULL){
          fbsource->setFeedbackSink(NULL);
        }
      }
      subscribers.erase(it++);
    }
    subscribers.clear();
    ELOG_DEBUG ("ClosedAll media in this OneToMany");
  }

}/* namespace erizo */

<commit_msg>Cleanup<commit_after>/*
 * OneToManyProcessor.cpp
 */

#include "OneToManyProcessor.h"
#include "WebRtcConnection.h"
#include "rtp/RtpHeaders.h"

namespace erizo {
  DEFINE_LOGGER(OneToManyProcessor, "OneToManyProcessor");
  OneToManyProcessor::OneToManyProcessor() {
    ELOG_DEBUG ("OneToManyProcessor constructor");
    feedbackSink_ = NULL;
  }

  OneToManyProcessor::~OneToManyProcessor() {
    ELOG_DEBUG ("OneToManyProcessor destructor");
    this->closeAll();
  }

  int OneToManyProcessor::deliverAudioData_(char* buf, int len) {
 //   ELOG_DEBUG ("OneToManyProcessor deliverAudio");
    if (len <= 0)
      return 0;

    boost::unique_lock<boost::mutex> lock(myMonitor_);
    if(subscribers.empty())
      return 0;

    std::map<std::string, sink_ptr>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      (*it).second->deliverAudioData(buf, len);
    }

    return 0;
  }

  int OneToManyProcessor::deliverVideoData_(char* buf, int len) {
    if (len <= 0)
      return 0;
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(buf);
    if(head->isFeedback()){
      ELOG_WARN("Receiving Feedback in wrong path: %d", head->packettype);
      if (feedbackSink_!=NULL){
        head->ssrc = htonl(publisher->getVideoSourceSSRC());
        feedbackSink_->deliverFeedback(buf,len);
      }
      return 0;
    }
    boost::unique_lock<boost::mutex> lock(myMonitor_);
    if (subscribers.empty())
      return 0;
    std::map<std::string, sink_ptr>::iterator it;
    for (it = subscribers.begin(); it != subscribers.end(); ++it) {
      if((*it).second != NULL) {
        (*it).second->deliverVideoData(buf, len);
      }
    }
    return 0;
  }

  void OneToManyProcessor::setPublisher(MediaSource* webRtcConn) {
    boost::mutex::scoped_lock lock(myMonitor_);
    this->publisher.reset(webRtcConn);
    feedbackSink_ = publisher->getFeedbackSink();
  }

  int OneToManyProcessor::deliverFeedback_(char* buf, int len){
    if (feedbackSink_ != NULL){
      feedbackSink_->deliverFeedback(buf,len);
    }
    return 0;
  }

  void OneToManyProcessor::addSubscriber(MediaSink* webRtcConn,
      const std::string& peerId) {
    ELOG_DEBUG("Adding subscriber");
    boost::mutex::scoped_lock lock(myMonitor_);
    ELOG_DEBUG("From %u, %u ", publisher->getAudioSourceSSRC() , publisher->getVideoSourceSSRC());
    webRtcConn->setAudioSinkSSRC(this->publisher->getAudioSourceSSRC());
    webRtcConn->setVideoSinkSSRC(this->publisher->getVideoSourceSSRC());
    ELOG_DEBUG("Subscribers ssrcs: Audio %u, video, %u from %u, %u ", webRtcConn->getAudioSinkSSRC(), webRtcConn->getVideoSinkSSRC(), this->publisher->getAudioSourceSSRC() , this->publisher->getVideoSourceSSRC());
    FeedbackSource* fbsource = webRtcConn->getFeedbackSource();

    if (fbsource!=NULL){
      ELOG_DEBUG("adding fbsource");
      fbsource->setFeedbackSink(this);
    }
    this->subscribers[peerId] = sink_ptr(webRtcConn);
  }

  void OneToManyProcessor::removeSubscriber(const std::string& peerId) {
    ELOG_DEBUG("Remove subscriber");
    boost::mutex::scoped_lock lock(myMonitor_);
    if (this->subscribers.find(peerId) != subscribers.end()) {
      this->subscribers.erase(peerId);
    }
  }

  void OneToManyProcessor::closeAll() {
    ELOG_DEBUG ("OneToManyProcessor closeAll");
    feedbackSink_ = NULL;
    publisher.reset();
    boost::unique_lock<boost::mutex> lock(myMonitor_);
    std::map<std::string, boost::shared_ptr<MediaSink> >::iterator it = subscribers.begin();
    while (it != subscribers.end()) {
      if ((*it).second != NULL) {
        FeedbackSource* fbsource = (*it).second->getFeedbackSource();
        if (fbsource!=NULL){
          fbsource->setFeedbackSink(NULL);
        }
      }
      subscribers.erase(it++);
    }
    subscribers.clear();
    ELOG_DEBUG ("ClosedAll media in this OneToMany");
  }

}/* namespace erizo */

<|endoftext|>


<commit_before>#include <Arduino.h>
#include <Stream.h>

#include <ESP8266WiFi.h>
ADC_MODE(ADC_VCC);
//#include <ESP8266WiFiMulti.h>

//AWS
#include <sha256.h>
#include <Utils.h>
#include <AWSClient2.h>

//WEBSockets
#include <Hash.h>
#include <WebSocketsClient.h>

//MQTT PAHO
#include <SPI.h>
#include <IPStack.h>
#include <MQTTClient.h>
#include <Countdown.h>

//AWS MQTT Websocket
#include <Client.h>
#include <AWSWebSocketClient.h>
#include <CircularByteBuffer.h>

#include <DHT.h>
#include <DHT_U.h>
#define AM2302_WIRE_BUS 4
#define DHTTYPE DHT22   // DHT 22  (AM2302)

#include "wifi_config.h"
#include "aws-iot-config.h"

//AWS IOT config, change these:
char wifi_ssid[]       = WIFI_SSID;
char wifi_password[]   = WIFI_PASSWORD;

//MQTT config
const int maxMQTTpackageSize = 512;
const int maxMQTTMessageHandlers = 1;

//ESP8266WiFiMulti WiFiMulti;

AWSWebSocketClient awsWSclient(1000);

IPStack ipstack(awsWSclient);
MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> *client = NULL;

DHT dht(AM2302_WIRE_BUS, DHTTYPE);

//# of connections
long connection = 0;

//generate random mqtt clientID
char* generateClientID () {
  char* cID = new char[23]();
  for (int i=0; i<22; i+=1)
    cID[i]=(char)random(1, 256);
  return cID;
}

//count messages arrived
int arrivedcount = 0;

//callback to handle mqtt messages
void messageArrived(MQTT::MessageData& md)
{
  MQTT::Message &message = md.message;

  Serial.print("Message ");
  Serial.print(++arrivedcount);
  Serial.print(" arrived: qos ");
  Serial.print(message.qos);
  Serial.print(", retained ");
  Serial.print(message.retained);
  Serial.print(", dup ");
  Serial.print(message.dup);
  Serial.print(", packetid ");
  Serial.println(message.id);
  Serial.print("Payload ");
  char* msg = new char[message.payloadlen+1]();
  memcpy (msg,message.payload,message.payloadlen);
  Serial.println(msg);
  delete msg;
}

//connects to websocket layer and mqtt layer
bool connect () {

    if (client == NULL) {
      client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack);
    } else {

      if (client->isConnected ()) {
        client->disconnect ();
      }
      delete client;
      client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack);
    }

    //delay is not necessary... it just help us to get a "trustful" heap space value
    delay (1000);
    Serial.print (millis ());
    Serial.print (" - conn: ");
    Serial.print (++connection);
    Serial.print (" - (");
    Serial.print (ESP.getFreeHeap ());
    Serial.println (")");

   int rc = ipstack.connect(aws_endpoint, port);
    if (rc != 1)
    {
      Serial.println("error connection to the websocket server");
      return false;
    } else {
      Serial.println("websocket layer connected");
    }

    Serial.println("MQTT connecting");
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    char* clientID = generateClientID ();
    data.clientID.cstring = clientID;
    rc = client->connect(data);
    delete[] clientID;
    if (rc != 0)
    {
      Serial.print("error connection to MQTT server");
      Serial.println(rc);
      return false;
    }
    Serial.println("MQTT connected");
    return true;
}

//subscribe to a mqtt topic
void subscribe () {
   //subscript to a topic
    int rc = client->subscribe(aws_topic, MQTT::QOS0, messageArrived);
    if (rc != 0) {
      Serial.print("rc from MQTT subscribe is ");
      Serial.println(rc);
      return;
    }
    Serial.println("MQTT subscribed");
}

//send a message to a mqtt topic
// void sendmessage () {
//     //send a message
//     MQTT::Message message;
//     char buf[100];
//     strcpy(buf, "{\"state\":{\"reported\":{\"on\": false}, \"desired\":{\"on\": false}}}");
//     message.qos = MQTT::QOS0;
//     message.retained = false;
//     message.dup = false;
//     message.payload = (void*)buf;
//     message.payloadlen = strlen(buf)+1;
//     int rc = client->publish(aws_topic, message);
// }

void sendmessage () {
    //send a message
    MQTT::Message message;
    char buf[100];

    float h = dht.readHumidity();

    // Read temperature as Celsius
    float t = dht.readTemperature();

    char strTemperature[8];
    char strRH[8];

    dtostrf(t, 2, 2, strTemperature);
    dtostrf(h, 2, 2, strRH);

    double voltage = ESP.getVcc()/1000.0;
    //Serial.print("Voltage is ");
    //Serial.println(voltage);

    //String messagebody = String( "{\"state\":{") + "\"temperature\":\"" + strTemperature + "\"" + ", \"humidity\":\"" + strRH + "\"" "}}"  ;
    String messagebody = String( "{\"state\":{") + "\"reported\":{" + "\"temperature\":\"" + t + "\"" + ", \"humidity\":\"" + h + "\"" + ", \"voltage\":\"" + voltage + "\"" "}}}"  ;

    Serial.println(aws_topic);
    Serial.println(messagebody);

    strcpy(buf, messagebody.c_str());
    //strcpy(buf, "{\"state\":{\"reported\":{\"temperature\": false}, \"desired\":{\"on\": false}}}");
    message.qos = MQTT::QOS1;
    message.retained = true;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
    int rc = client->publish(aws_topic, message);
}

void setup() {
    Serial.begin (115200);
    delay (2000);
    Serial.setDebugOutput(1);

    dht.begin();

    //fill with ssid and wifi password
    //WiFiMulti.addAP(wifi_ssid, wifi_password);
    WiFi.begin(wifi_ssid, wifi_password);

    Serial.println ("connecting to wifi");
    while(WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print (".");
    }
    Serial.println ("\nconnected");

    //fill AWS parameters
    awsWSclient.setAWSRegion(aws_region);
    awsWSclient.setAWSDomain(aws_endpoint);
    awsWSclient.setAWSKeyID(aws_key);
    awsWSclient.setAWSSecretKey(aws_secret);
    awsWSclient.setUseSSL(true);

    if (connect ()){
      subscribe ();
      sendmessage ();
    }

}

void loop() {

  //keep the mqtt up and running
  if (awsWSclient.connected ()) {
      client->yield();
      sendmessage();
  } else {
    //handle reconnection
    if (connect ()){
//      subscribe ();
    }
  }
  ESP.deepSleep(15 * 60* 1000000);
  //ESP.deepSleep(1 * 60* 1000000);
}
<commit_msg>Switch esp to station mode. Useful when a fresh chip is flashed for the first time deep sleep with a wakeup option with default RF state<commit_after>#include <Arduino.h>
#include <Stream.h>

#include <ESP8266WiFi.h>
ADC_MODE(ADC_VCC);
//#include <ESP8266WiFiMulti.h>

//AWS
#include <sha256.h>
#include <Utils.h>
#include <AWSClient2.h>

//WEBSockets
#include <Hash.h>
#include <WebSocketsClient.h>

//MQTT PAHO
#include <SPI.h>
#include <IPStack.h>
#include <MQTTClient.h>
#include <Countdown.h>

//AWS MQTT Websocket
#include <Client.h>
#include <AWSWebSocketClient.h>
#include <CircularByteBuffer.h>

#include <DHT.h>
#include <DHT_U.h>
#define AM2302_WIRE_BUS 4
#define DHTTYPE DHT22   // DHT 22  (AM2302)

#include "wifi_config.h"
#include "aws-iot-config.h"

//AWS IOT config, change these:
char wifi_ssid[]       = WIFI_SSID;
char wifi_password[]   = WIFI_PASSWORD;

//MQTT config
const int maxMQTTpackageSize = 512;
const int maxMQTTMessageHandlers = 1;

//ESP8266WiFiMulti WiFiMulti;

AWSWebSocketClient awsWSclient(1000);

IPStack ipstack(awsWSclient);
MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> *client = NULL;

DHT dht(AM2302_WIRE_BUS, DHTTYPE);

//# of connections
long connection = 0;

//generate random mqtt clientID
char* generateClientID () {
  char* cID = new char[23]();
  for (int i=0; i<22; i+=1)
    cID[i]=(char)random(1, 256);
  return cID;
}

//count messages arrived
int arrivedcount = 0;

//callback to handle mqtt messages
void messageArrived(MQTT::MessageData& md)
{
  MQTT::Message &message = md.message;

  Serial.print("Message ");
  Serial.print(++arrivedcount);
  Serial.print(" arrived: qos ");
  Serial.print(message.qos);
  Serial.print(", retained ");
  Serial.print(message.retained);
  Serial.print(", dup ");
  Serial.print(message.dup);
  Serial.print(", packetid ");
  Serial.println(message.id);
  Serial.print("Payload ");
  char* msg = new char[message.payloadlen+1]();
  memcpy (msg,message.payload,message.payloadlen);
  Serial.println(msg);
  delete msg;
}

//connects to websocket layer and mqtt layer
bool connect () {

    if (client == NULL) {
      client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack);
    } else {

      if (client->isConnected ()) {
        client->disconnect ();
      }
      delete client;
      client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack);
    }

    //delay is not necessary... it just help us to get a "trustful" heap space value
    delay (1000);
    Serial.print (millis ());
    Serial.print (" - conn: ");
    Serial.print (++connection);
    Serial.print (" - (");
    Serial.print (ESP.getFreeHeap ());
    Serial.println (")");

   int rc = ipstack.connect(aws_endpoint, port);
    if (rc != 1)
    {
      Serial.println("error connection to the websocket server");
      return false;
    } else {
      Serial.println("websocket layer connected");
    }

    Serial.println("MQTT connecting");
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    char* clientID = generateClientID ();
    data.clientID.cstring = clientID;
    rc = client->connect(data);
    delete[] clientID;
    if (rc != 0)
    {
      Serial.print("error connection to MQTT server");
      Serial.println(rc);
      return false;
    }
    Serial.println("MQTT connected");
    return true;
}

//subscribe to a mqtt topic
void subscribe () {
   //subscript to a topic
    int rc = client->subscribe(aws_topic, MQTT::QOS0, messageArrived);
    if (rc != 0) {
      Serial.print("rc from MQTT subscribe is ");
      Serial.println(rc);
      return;
    }
    Serial.println("MQTT subscribed");
}

//send a message to a mqtt topic
// void sendmessage () {
//     //send a message
//     MQTT::Message message;
//     char buf[100];
//     strcpy(buf, "{\"state\":{\"reported\":{\"on\": false}, \"desired\":{\"on\": false}}}");
//     message.qos = MQTT::QOS0;
//     message.retained = false;
//     message.dup = false;
//     message.payload = (void*)buf;
//     message.payloadlen = strlen(buf)+1;
//     int rc = client->publish(aws_topic, message);
// }

void sendmessage () {
    //send a message
    MQTT::Message message;
    char buf[100];

    float h = dht.readHumidity();

    // Read temperature as Celsius
    float t = dht.readTemperature();

    char strTemperature[8];
    char strRH[8];

    dtostrf(t, 2, 2, strTemperature);
    dtostrf(h, 2, 2, strRH);

    double voltage = ESP.getVcc()/1000.0;
    //Serial.print("Voltage is ");
    //Serial.println(voltage);

    //String messagebody = String( "{\"state\":{") + "\"temperature\":\"" + strTemperature + "\"" + ", \"humidity\":\"" + strRH + "\"" "}}"  ;
    String messagebody = String( "{\"state\":{") + "\"reported\":{" + "\"temperature\":\"" + t + "\"" + ", \"humidity\":\"" + h + "\"" + ", \"voltage\":\"" + voltage + "\"" "}}}"  ;

    Serial.println(aws_topic);
    Serial.println(messagebody);

    strcpy(buf, messagebody.c_str());
    //strcpy(buf, "{\"state\":{\"reported\":{\"temperature\": false}, \"desired\":{\"on\": false}}}");
    message.qos = MQTT::QOS1;
    message.retained = true;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
    int rc = client->publish(aws_topic, message);
}

void setup() {
    Serial.begin (115200);
    delay (2000);
    Serial.setDebugOutput(1);

    dht.begin();

    //fill with ssid and wifi password
    //WiFiMulti.addAP(wifi_ssid, wifi_password);
    //WiFi.setOutputPower(0);
    WiFi.mode(WIFI_STA);
    WiFi.begin(wifi_ssid, wifi_password);

    Serial.println ("connecting to wifi");
    while(WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print (".");
    }
    Serial.println ("\nconnected");

    //fill AWS parameters
    awsWSclient.setAWSRegion(aws_region);
    awsWSclient.setAWSDomain(aws_endpoint);
    awsWSclient.setAWSKeyID(aws_key);
    awsWSclient.setAWSSecretKey(aws_secret);
    awsWSclient.setUseSSL(true);

    if (connect ()){
      subscribe ();
      sendmessage ();
    }

}

void loop() {

  //keep the mqtt up and running
  if (awsWSclient.connected ()) {
      client->yield();
      sendmessage();
  } else {
    //handle reconnection
    if (connect ()){
//      subscribe ();
    }
  }
  ESP.deepSleep(15 * 60* 1000000,WAKE_RF_DEFAULT);
  //ESP.deepSleep(1 * 60* 1000000,WAKE_RF_DEFAULT);
}
<|endoftext|>


<commit_before>
#include <random>

#include "quantities/si.hpp"
#include "numerics/чебышёв_series.hpp"

// Must come last to avoid conflicts when defining the CHECK macros.
#include "benchmark/benchmark.h"

namespace principia {

using numerics::ЧебышёвSeries;
using si::Second;

namespace benchmarks {

namespace {
int const kEvaluationsPerIteration = 1000;
}  // namespace

void BM_EvaluateDouble(benchmark::State& state) {
  state.PauseTiming();
  int const degree = state.range_x();
  std::mt19937_64 random(42);
  std::vector<double> coefficients;
  for (int i = 0; i <= degree; ++i) {
    coefficients.push_back(static_cast<double>(random()));
  }
  Instant const t_min(random() * Second);
  Instant const t_max = t_min + random() * Second;
  ЧебышёвSeries<double> const series(coefficients, t_min, t_max);

  Instant t = t_min;
  Time const ∆t = (t_max - t_min) * 1E-9;
  double result = 0.0;

  state.ResumeTiming();
  while (state.KeepRunning()) {
    for (int i = 0; i < kEvaluationsPerIteration; ++i) {
      result += series.Evaluate(t);
      t += ∆t;
    }
  }
  state.PauseTiming();

  // This weird call to |SetLabel| has no effect except that it uses |result|
  // and therefore prevents the loop from being optimized away.
  state.SetLabel(std::to_string(result).substr(0, 0));
}

BENCHMARK(BM_EvaluateDouble)->Arg(4)->Arg(8)->Arg(16);

}  // namespace benchmarks
}  // namespace principia
<commit_msg>Numbers.<commit_after>// C:\Users\phl\Projects\GitHub\Principia [Series +0 ~1 -0]> .\Release\benchmarks.exe --benchmark_filter=Evaluate  // NOLINT(whitespace/line_length)
// Benchmarking on 1 X 3310 MHz CPU
// 2015/05/15-18:21:37
// Benchmark              Time(ns)    CPU(ns) Iterations
// -----------------------------------------------------
// BM_EvaluateDouble/4       11859      12009      42869
// BM_EvaluateDouble/8       18978      19040      27038
// BM_EvaluateDouble/15      40024      40119      12832
// BM_EvaluateDouble/16      38326      38407      13404
// BM_EvaluateDouble/17      43830      44042      11689
// BM_EvaluateDouble/18      49399      49519      10396
// BM_EvaluateDouble/19      54013      54121       9512

#include <random>

#include "quantities/si.hpp"
#include "numerics/чебышёв_series.hpp"

// Must come last to avoid conflicts when defining the CHECK macros.
#include "benchmark/benchmark.h"

namespace principia {

using numerics::ЧебышёвSeries;
using si::Second;

namespace benchmarks {

namespace {
int const kEvaluationsPerIteration = 1000;
}  // namespace

void BM_EvaluateDouble(benchmark::State& state) {
  state.PauseTiming();
  int const degree = state.range_x();
  std::mt19937_64 random(42);
  std::vector<double> coefficients;
  for (int i = 0; i <= degree; ++i) {
    coefficients.push_back(static_cast<double>(random()));
  }
  Instant const t_min(random() * Second);
  Instant const t_max = t_min + random() * Second;
  ЧебышёвSeries<double> const series(coefficients, t_min, t_max);

  Instant t = t_min;
  Time const ∆t = (t_max - t_min) * 1E-9;
  double result = 0.0;

  state.ResumeTiming();
  while (state.KeepRunning()) {
    for (int i = 0; i < kEvaluationsPerIteration; ++i) {
      result += series.Evaluate(t);
      t += ∆t;
    }
  }
  state.PauseTiming();

  // This weird call to |SetLabel| has no effect except that it uses |result|
  // and therefore prevents the loop from being optimized away.
  state.SetLabel(std::to_string(result).substr(0, 0));
}

BENCHMARK(BM_EvaluateDouble)->
    Arg(4)->Arg(8)->Arg(15)->Arg(16)->Arg(17)->Arg(18)->Arg(19);

}  // namespace benchmarks
}  // namespace principia
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/torrent_info.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

    std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
    {
        return i.trackers().begin();
    }

    std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
    {
        return i.trackers().end();
    }

    void add_node(torrent_info& ti, char const* hostname, int port)
    {
        ti.add_node(std::make_pair(hostname, port));
    }

    list nodes(torrent_info const& ti)
    {
        list result;

        typedef std::vector<std::pair<std::string, int> > list_type;

        for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
        {
            result.append(make_tuple(i->first, i->second));
        }

        return result;
    }

    file_storage::iterator begin_files(torrent_info& i)
    {
        return i.begin_files();
    }

    file_storage::iterator end_files(torrent_info& i)
    {
        return i.end_files();
    }

    //list files(torrent_info const& ti, bool storage) {
    list files(torrent_info const& ti, bool storage) {
        list result;

        typedef std::vector<file_entry> list_type;

        for (list_type::const_iterator i = ti.begin_files(); i != ti.end_files(); ++i)
            result.append(*i);

        return result;
    }

    std::string metadata(torrent_info const& ti) {
        std::string result(ti.metadata().get(), ti.metadata_size());
        return result;
    }
} // namespace unnamed

void bind_torrent_info()
{
    return_value_policy<copy_const_reference> copy;

    class_<torrent_info, boost::intrusive_ptr<torrent_info> >("torrent_info", no_init)
        .def(init<entry const&>())
        .def(init<sha1_hash const&>())
        .def(init<char const*, int>())
        .def(init<char const*>())

        .def("add_tracker", &torrent_info::add_tracker, (arg("url"), arg("tier")=0))
        .def("add_url_seed", &torrent_info::add_url_seed)

        .def("name", &torrent_info::name, copy)
        .def("comment", &torrent_info::comment, copy)
        .def("creator", &torrent_info::creator, copy)
        .def("total_size", &torrent_info::total_size)
        .def("piece_length", &torrent_info::piece_length)
        .def("num_pieces", &torrent_info::num_pieces)
        .def("info_hash", &torrent_info::info_hash, copy)

        .def("hash_for_piece", &torrent_info::hash_for_piece)
        .def("piece_size", &torrent_info::piece_size)

        .def("num_files", &torrent_info::num_files, (arg("storage")=false))
        .def("file_at", &torrent_info::file_at, return_internal_reference<>())
        .def("files", &files, (arg("storage")=false))

        .def("priv", &torrent_info::priv)
        .def("trackers", range(begin_trackers, end_trackers))

        .def("creation_date", &torrent_info::creation_date)

        .def("add_node", &add_node)
        .def("nodes", &nodes)
        .def("metadata", &metadata)
        .def("metadata_size", &torrent_info::metadata_size)
        ;

    class_<file_entry>("file_entry")
       .add_property(
            "path"
          , make_getter(
                &file_entry::path, return_value_policy<copy_non_const_reference>()
            )
        )
        .def_readonly("offset", &file_entry::offset)
        .def_readonly("size", &file_entry::size)
        ;

    class_<announce_entry>("announce_entry", init<std::string const&>())
        .def_readwrite("url", &announce_entry::url)
        .def_readwrite("tier", &announce_entry::tier)
        ;
}

<commit_msg>Fix segfault in python bindings when passing None to torrent_info()<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/torrent_info.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

    std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
    {
        return i.trackers().begin();
    }

    std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
    {
        return i.trackers().end();
    }

    void add_node(torrent_info& ti, char const* hostname, int port)
    {
        ti.add_node(std::make_pair(hostname, port));
    }

    list nodes(torrent_info const& ti)
    {
        list result;

        typedef std::vector<std::pair<std::string, int> > list_type;

        for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
        {
            result.append(make_tuple(i->first, i->second));
        }

        return result;
    }

    file_storage::iterator begin_files(torrent_info& i)
    {
        return i.begin_files();
    }

    file_storage::iterator end_files(torrent_info& i)
    {
        return i.end_files();
    }

    //list files(torrent_info const& ti, bool storage) {
    list files(torrent_info const& ti, bool storage) {
        list result;

        typedef std::vector<file_entry> list_type;

        for (list_type::const_iterator i = ti.begin_files(); i != ti.end_files(); ++i)
            result.append(*i);

        return result;
    }

    std::string metadata(torrent_info const& ti) {
        std::string result(ti.metadata().get(), ti.metadata_size());
        return result;
    }
} // namespace unnamed

void bind_torrent_info()
{
    return_value_policy<copy_const_reference> copy;

    class_<torrent_info, boost::intrusive_ptr<torrent_info> >("torrent_info", no_init)
        .def(init<entry const&>())
        .def(init<sha1_hash const&>())
        .def(init<char const*, int>())

        .def("add_tracker", &torrent_info::add_tracker, (arg("url"), arg("tier")=0))
        .def("add_url_seed", &torrent_info::add_url_seed)

        .def("name", &torrent_info::name, copy)
        .def("comment", &torrent_info::comment, copy)
        .def("creator", &torrent_info::creator, copy)
        .def("total_size", &torrent_info::total_size)
        .def("piece_length", &torrent_info::piece_length)
        .def("num_pieces", &torrent_info::num_pieces)
        .def("info_hash", &torrent_info::info_hash, copy)

        .def("hash_for_piece", &torrent_info::hash_for_piece)
        .def("piece_size", &torrent_info::piece_size)

        .def("num_files", &torrent_info::num_files, (arg("storage")=false))
        .def("file_at", &torrent_info::file_at, return_internal_reference<>())
        .def("files", &files, (arg("storage")=false))

        .def("priv", &torrent_info::priv)
        .def("trackers", range(begin_trackers, end_trackers))

        .def("creation_date", &torrent_info::creation_date)

        .def("add_node", &add_node)
        .def("nodes", &nodes)
        .def("metadata", &metadata)
        .def("metadata_size", &torrent_info::metadata_size)
        ;

    class_<file_entry>("file_entry")
       .add_property(
            "path"
          , make_getter(
                &file_entry::path, return_value_policy<copy_non_const_reference>()
            )
        )
        .def_readonly("offset", &file_entry::offset)
        .def_readonly("size", &file_entry::size)
        ;

    class_<announce_entry>("announce_entry", init<std::string const&>())
        .def_readwrite("url", &announce_entry::url)
        .def_readwrite("tier", &announce_entry::tier)
        ;
}

<|endoftext|>


<commit_before>/* bzflag
* Copyright (c) 1993 - 2008 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named LICENSE that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "Reports.h"
#include "bzfsAPI.h"
#include "WorldEventManager.h"
#include "bzfs.h"
#include "time.h"
#include "bzglob.h"

/** initialize the singleton */
template <>
Reports* Singleton<Reports>::_instance = (Reports*)0;

/**
* default constructor, protected because of singleton
*/
Reports::Reports() : Singleton<Reports>()
{
}

Reports::~Reports()
{

}

bool Reports::file(const std::string &user, const std::string message)
{
  time_t now = time(NULL);

  Report report(ctime(&now), user, message);

  if(clOptions->reportFile.size()) {
    std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out | std::ios::app);
    ofs << report.fileLine() << std::endl;
  }

  if(clOptions->reportPipe.size() > 0) {
    FILE* pipeWrite = popen(clOptions->reportPipe.c_str(), "w");
    if(pipeWrite != NULL)
      fprintf(pipeWrite, "%s\n\n", report.fileLine().c_str());
    else
      logDebugMessage(1, "Couldn't write report to the pipe\n");
    pclose(pipeWrite);
  }

  std::string temp = std::string("**\"") + user + "\" reports: " + message;
  const std::vector<std::string> words = TextUtils::tokenize(temp, " \t");
  unsigned int cur = 0;
  const unsigned int wordsize = words.size();
  std::string temp2;

  while(cur != wordsize) {
    temp2.clear();
    while(cur != wordsize &&(temp2.size() + words[cur].size() + 1) <(unsigned) MessageLen) {
	temp2 += words[cur] + " ";
	++cur;
    }
    sendMessage(ServerPlayer, AdminPlayers, temp2.c_str());
  }

  logDebugMessage(1, "A report from %s has been filed(time: %s).\n", report.from.c_str(), report.time.c_str());

  // Notify plugins of the report filed
  bz_ReportFiledEventData_V1 reportData;
  reportData.from = user;
  reportData.message = message;
  worldEventManager.callEvents(bz_eReportFiledEvent, &reportData);

  return true;
}

size_t Reports::getLines(std::vector<std::string> &lines, const char* p)
{
  lines.clear();
  if(clOptions->reportFile.size() > 0)
    return 0;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if(ifs.fail())
    return 0;

  std::string pattern = "*";
  if(p)
    pattern = p;

  // assumes that empty lines separate the reports

  bool done = false;
  while(!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if(line.size()) {
      Report report(line);

      if(report.match(pattern))
	lines.push_back(report.fileLine());
    }
  }
  return lines.size();
}

size_t Reports::count(void)
{
  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if(ifs.fail())
    return 0;

  size_t s = 0;

  bool done = false;
  while(!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if(line.size())
      s++;
  }
  return s;
}

bool Reports::clear(void)
{
  // just blast out the file with a single newline
  if(!clOptions->reportFile.size()) {
    std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out);
    ofs << std::endl;
    return true;
  }

  return false;
}

bool Reports::clear(size_t index)
{
  if(!clOptions->reportFile.size())
    return false;

  std::vector<Report> reports;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if(ifs.fail())
    return false;

  // read em all in
  bool done = false;
  while(!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if(line.size())
      reports.push_back(Report(line));
  }
  ifs.close();

  if(index >= reports.size())
    return false;

  reports.erase(reports.begin()+index);

  std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out);

  std::vector<Report>::iterator itr = reports.begin();
  while(itr != reports.end())
  for(size_t r = 0; r < reports.size(); r++)
    ofs <<(itr++)->fileLine() << std::endl;

  return true;
}

Reports::Report Reports::get(size_t index)
{
  if(!clOptions->reportFile.size())
    return Report();

  std::list<Report> reports;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if(ifs.fail())
    return Report();

  size_t s = 0;
  // read em all in
  bool done = false;
  while(!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if(line.size()) {
      if(s == index)
	return Report(line);
      s++;
    }
  }
  ifs.close();

  return Report();
}

Reports::Report::Report(const char* t, const std::string &f, const std::string & m)
{
  if(t)
    time = t;

  from = f;
  message = m;
}

bool Reports::Report::fill(const std::string &line)
{
  std::vector<std::string> parts = TextUtils::tokenize(line, std::string(":"), 3, false);
  if(parts.size() >= 4) {
    time = parts[0];
    from = parts[2];
    message = parts[3];
  }
  else
    from = time = message = "";
  return time.size() > 0;
}

std::string Reports::Report::fileLine(void)
{
  return time + ":Reported by :" + from + ":" + message;
}

bool Reports::Report::matchName(const std::string pattern)
{
  return glob_match(pattern, TextUtils::toupper(from));
}

bool Reports::Report::matchMessage(const std::string pattern)
{
  return glob_match(pattern, TextUtils::toupper(message));
}

bool Reports::Report::match(const std::string pattern)
{
  return matchMessage(pattern)|| matchName(pattern);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>what dummy shoved the parens up next to the built-ins? oh wait, that was me.<commit_after>/* bzflag
* Copyright (c) 1993 - 2008 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named LICENSE that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "Reports.h"
#include "bzfsAPI.h"
#include "WorldEventManager.h"
#include "bzfs.h"
#include "time.h"
#include "bzglob.h"

/** initialize the singleton */
template <>
Reports* Singleton<Reports>::_instance = (Reports*)0;

/**
* default constructor, protected because of singleton
*/
Reports::Reports() : Singleton<Reports>()
{
}

Reports::~Reports()
{

}

bool Reports::file(const std::string &user, const std::string message)
{
  time_t now = time(NULL);

  Report report(ctime(&now), user, message);

  if (clOptions->reportFile.size()) {
    std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out | std::ios::app);
    ofs << report.fileLine() << std::endl;
  }

  if (clOptions->reportPipe.size() > 0) {
    FILE* pipeWrite = popen(clOptions->reportPipe.c_str(), "w");
    if (pipeWrite != NULL)
      fprintf(pipeWrite, "%s\n\n", report.fileLine().c_str());
    else
      logDebugMessage(1, "Couldn't write report to the pipe\n");
    pclose(pipeWrite);
  }

  std::string temp = std::string("**\"") + user + "\" reports: " + message;
  const std::vector<std::string> words = TextUtils::tokenize(temp, " \t");
  unsigned int cur = 0;
  const unsigned int wordsize = words.size();
  std::string temp2;

  while (cur != wordsize) {
    temp2.clear();
    while (cur != wordsize &&(temp2.size() + words[cur].size() + 1) <(unsigned) MessageLen) {
	temp2 += words[cur] + " ";
	++cur;
    }
    sendMessage(ServerPlayer, AdminPlayers, temp2.c_str());
  }

  logDebugMessage(1, "A report from %s has been filed(time: %s).\n", report.from.c_str(), report.time.c_str());

  // Notify plugins of the report filed
  bz_ReportFiledEventData_V1 reportData;
  reportData.from = user;
  reportData.message = message;
  worldEventManager.callEvents(bz_eReportFiledEvent, &reportData);

  return true;
}

size_t Reports::getLines(std::vector<std::string> &lines, const char* p)
{
  lines.clear();
  if (clOptions->reportFile.size() > 0)
    return 0;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if (ifs.fail())
    return 0;

  std::string pattern = "*";
  if (p)
    pattern = p;

  // assumes that empty lines separate the reports

  bool done = false;
  while (!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if (line.size()) {
      Report report(line);

      if (report.match(pattern))
	lines.push_back(report.fileLine());
    }
  }
  return lines.size();
}

size_t Reports::count(void)
{
  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if (ifs.fail())
    return 0;

  size_t s = 0;

  bool done = false;
  while (!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if (line.size())
      s++;
  }
  return s;
}

bool Reports::clear(void)
{
  // just blast out the file with a single newline
  if (!clOptions->reportFile.size()) {
    std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out);
    ofs << std::endl;
    return true;
  }

  return false;
}

bool Reports::clear(size_t index)
{
  if (!clOptions->reportFile.size())
    return false;

  std::vector<Report> reports;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if (ifs.fail())
    return false;

  // read em all in
  bool done = false;
  while (!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if (line.size())
      reports.push_back(Report(line));
  }
  ifs.close();

  if (index >= reports.size())
    return false;

  reports.erase(reports.begin()+index);

  std::ofstream ofs(clOptions->reportFile.c_str(), std::ios::out);

  std::vector<Report>::iterator itr = reports.begin();
  while (itr != reports.end())
  for (size_t r = 0; r < reports.size(); r++)
    ofs <<(itr++)->fileLine() << std::endl;

  return true;
}

Reports::Report Reports::get(size_t index)
{
  if (!clOptions->reportFile.size())
    return Report();

  std::list<Report> reports;

  std::ifstream ifs(clOptions->reportFile.c_str(), std::ios::in);
  if (ifs.fail())
    return Report();

  size_t s = 0;
  // read em all in
  bool done = false;
  while (!done) {
    std::string line;
    done = std::getline(ifs, line) == NULL;
    if (line.size()) {
      if (s == index)
	return Report(line);
      s++;
    }
  }
  ifs.close();

  return Report();
}

Reports::Report::Report(const char* t, const std::string &f, const std::string & m)
{
  if (t)
    time = t;

  from = f;
  message = m;
}

bool Reports::Report::fill(const std::string &line)
{
  std::vector<std::string> parts = TextUtils::tokenize(line, std::string(":"), 3, false);
  if (parts.size() >= 4) {
    time = parts[0];
    from = parts[2];
    message = parts[3];
  } else {
    from = time = message = "";
  }
  return time.size() > 0;
}

std::string Reports::Report::fileLine(void)
{
  return time + ":Reported by :" + from + ":" + message;
}

bool Reports::Report::matchName(const std::string pattern)
{
  return glob_match(pattern, TextUtils::toupper(from));
}

bool Reports::Report::matchMessage(const std::string pattern)
{
  return glob_match(pattern, TextUtils::toupper(message));
}

bool Reports::Report::match(const std::string pattern)
{
  return matchMessage(pattern)|| matchName(pattern);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// AliFemtoBasicEventCut - the basic cut for events.                          //
// Only cuts on event multiplicity and z-vertex position                      //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "AliFemtoBasicEventCut.h"
//#include <cstdio>

#ifdef __ROOT__
ClassImp(AliFemtoBasicEventCut)
#endif

AliFemtoBasicEventCut::AliFemtoBasicEventCut() :
  AliFemtoEventCut(),
  fEventMult(),
  fVertZPos(),
  fAcceptBadVertex(false),
  fNEventsPassed(0),
  fNEventsFailed(0),
  fSelectTrigger(0)
{
  // Default constructor
  fEventMult[0] = 0;
  fEventMult[1] = 100000;
  fVertZPos[0] = -100.0;
  fVertZPos[1] = 100.0;
  fPsiEP[0] = -1000.0;
  fPsiEP[1] = 1000.0;
}
//------------------------------
AliFemtoBasicEventCut::~AliFemtoBasicEventCut(){
  // Default destructor
}
//------------------------------
bool AliFemtoBasicEventCut::Pass(const AliFemtoEvent* event){

  // Pass events if they fall within the multiplicity and z-vertex
  // position range. Fail otherwise
  //  int mult =  event->NumberOfTracks();
  int mult = (int) event->UncorrectedNumberOfPrimaries();
  double vertexZPos = event->PrimVertPos().z();

  // Double_t qxEPVZERO = 0, qyEPVZERO = 0;
  // Double_t qVZERO = -999;
  double epvzero = event->ReactionPlaneAngle();

  // cout << "AliFemtoBasicEventCut:: epvzero:       " << fPsiEP[0] << " < " << epvzero << " < " << fPsiEP[1] << endl;
//   cout << "AliFemtoBasicEventCut:: mult:       " << fEventMult[0] << " < " << mult << " < " << fEventMult[1] << endl;
//   cout << "AliFemtoBasicEventCut:: VertexZPos: " << fVertZPos[0] << " < " << vertexZPos << " < " << fVertZPos[1] << endl;
//   cout << "AliFemtoBasicEventCut:: VertexZErr: " << event->PrimVertCov()[4] << endl;

  // cout << "AliFemtoBasicEventCut:: MagneticField: " << event->MagneticField() << endl;
  // cout << "AliFemtoBasicEventCut:: IsCollisionCandidate: " << event->IsCollisionCandidate() << endl;
  // cout << "AliFemtoBasicEventCut:: TriggerCluster: " << event->TriggerCluster() << endl;
  // cout << "AliFemtoBasicEventCut:: fSelectTrigger: " << fSelectTrigger << endl;
  // cout << "AliFemtoBasicEventCut:: " << endl;
  bool goodEvent =
    ((mult >= fEventMult[0]) &&
     (mult <= fEventMult[1]) &&
     (vertexZPos > fVertZPos[0]) &&
     (vertexZPos < fVertZPos[1]) &&
     (epvzero > fPsiEP[0]) &&
     (epvzero < fPsiEP[1]) &&
     ((!fAcceptBadVertex) || (event->ZDCParticipants() > 1.0)) &&
      ((!fSelectTrigger) || (event->TriggerCluster() == fSelectTrigger))
);

  // cout << "AliFemtoBasicEventCut:: goodEvent" <<goodEvent << endl;

  goodEvent ? fNEventsPassed++ : fNEventsFailed++ ;
    cout << "AliFemtoBasicEventCut:: return : " << goodEvent << endl;
//     (fAcceptBadVertex || (event->PrimVertCov()[4] > -1000.0)) &&

  return (goodEvent);
}
//------------------------------
AliFemtoString AliFemtoBasicEventCut::Report(){
  // Prepare report
  string stemp;
  char ctemp[100];
  snprintf(ctemp , 100, "\nMultiplicity:\t %d-%d",fEventMult[0],fEventMult[1]);
  stemp = ctemp;
  snprintf(ctemp , 100, "\nVertex Z-position:\t %E-%E",fVertZPos[0],fVertZPos[1]);
  stemp += ctemp;
  snprintf(ctemp , 100, "\nNumber of events which passed:\t%ld  Number which failed:\t%ld",fNEventsPassed,fNEventsFailed);
  stemp += ctemp;
  AliFemtoString returnThis = stemp;
  return returnThis;
}
void AliFemtoBasicEventCut::SetAcceptBadVertex(bool b)
{
  fAcceptBadVertex = b;
}
bool AliFemtoBasicEventCut::GetAcceptBadVertex()
{
  return fAcceptBadVertex;
}

<commit_msg>commenting out not needed couts<commit_after>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// AliFemtoBasicEventCut - the basic cut for events.                          //
// Only cuts on event multiplicity and z-vertex position                      //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "AliFemtoBasicEventCut.h"
//#include <cstdio>

#ifdef __ROOT__
ClassImp(AliFemtoBasicEventCut)
#endif

AliFemtoBasicEventCut::AliFemtoBasicEventCut() :
  AliFemtoEventCut(),
  fEventMult(),
  fVertZPos(),
  fAcceptBadVertex(false),
  fNEventsPassed(0),
  fNEventsFailed(0),
  fSelectTrigger(0)
{
  // Default constructor
  fEventMult[0] = 0;
  fEventMult[1] = 100000;
  fVertZPos[0] = -100.0;
  fVertZPos[1] = 100.0;
  fPsiEP[0] = -1000.0;
  fPsiEP[1] = 1000.0;
}
//------------------------------
AliFemtoBasicEventCut::~AliFemtoBasicEventCut(){
  // Default destructor
}
//------------------------------
bool AliFemtoBasicEventCut::Pass(const AliFemtoEvent* event){

  // Pass events if they fall within the multiplicity and z-vertex
  // position range. Fail otherwise
  //  int mult =  event->NumberOfTracks();
  int mult = (int) event->UncorrectedNumberOfPrimaries();
  double vertexZPos = event->PrimVertPos().z();

  // Double_t qxEPVZERO = 0, qyEPVZERO = 0;
  // Double_t qVZERO = -999;
  double epvzero = event->ReactionPlaneAngle();

  // cout << "AliFemtoBasicEventCut:: epvzero:       " << fPsiEP[0] << " < " << epvzero << " < " << fPsiEP[1] << endl;
//   cout << "AliFemtoBasicEventCut:: mult:       " << fEventMult[0] << " < " << mult << " < " << fEventMult[1] << endl;
//   cout << "AliFemtoBasicEventCut:: VertexZPos: " << fVertZPos[0] << " < " << vertexZPos << " < " << fVertZPos[1] << endl;
//   cout << "AliFemtoBasicEventCut:: VertexZErr: " << event->PrimVertCov()[4] << endl;

  // cout << "AliFemtoBasicEventCut:: MagneticField: " << event->MagneticField() << endl;
  // cout << "AliFemtoBasicEventCut:: IsCollisionCandidate: " << event->IsCollisionCandidate() << endl;
  // cout << "AliFemtoBasicEventCut:: TriggerCluster: " << event->TriggerCluster() << endl;
  // cout << "AliFemtoBasicEventCut:: fSelectTrigger: " << fSelectTrigger << endl;
  // cout << "AliFemtoBasicEventCut:: " << endl;
  bool goodEvent =
    ((mult >= fEventMult[0]) &&
     (mult <= fEventMult[1]) &&
     (vertexZPos > fVertZPos[0]) &&
     (vertexZPos < fVertZPos[1]) &&
     (epvzero > fPsiEP[0]) &&
     (epvzero < fPsiEP[1]) &&
     ((!fAcceptBadVertex) || (event->ZDCParticipants() > 1.0)) &&
      ((!fSelectTrigger) || (event->TriggerCluster() == fSelectTrigger))
);

  // cout << "AliFemtoBasicEventCut:: goodEvent" <<goodEvent << endl;

  goodEvent ? fNEventsPassed++ : fNEventsFailed++ ;
  // cout << "AliFemtoBasicEventCut:: return : " << goodEvent << endl;
//     (fAcceptBadVertex || (event->PrimVertCov()[4] > -1000.0)) &&

  return (goodEvent);
}
//------------------------------
AliFemtoString AliFemtoBasicEventCut::Report(){
  // Prepare report
  string stemp;
  char ctemp[100];
  snprintf(ctemp , 100, "\nMultiplicity:\t %d-%d",fEventMult[0],fEventMult[1]);
  stemp = ctemp;
  snprintf(ctemp , 100, "\nVertex Z-position:\t %E-%E",fVertZPos[0],fVertZPos[1]);
  stemp += ctemp;
  snprintf(ctemp , 100, "\nNumber of events which passed:\t%ld  Number which failed:\t%ld",fNEventsPassed,fNEventsFailed);
  stemp += ctemp;
  AliFemtoString returnThis = stemp;
  return returnThis;
}
void AliFemtoBasicEventCut::SetAcceptBadVertex(bool b)
{
  fAcceptBadVertex = b;
}
bool AliFemtoBasicEventCut::GetAcceptBadVertex()
{
  return fAcceptBadVertex;
}

<|endoftext|>