<commit_before>/*************************************************************************
 *
 *  $RCSfile: sddll.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2004-10-04 18:20:43 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif

#include <svx/editeng.hxx>

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#ifndef _FM_FMOBJFAC_HXX
#include <svx/fmobjfac.hxx>
#endif
#ifndef _SVX_SIIMPORT_HXX
#include <svx/siimport.hxx>
#endif
#ifndef _SVDFIELD_HXX
#include <svx/svdfield.hxx>
#endif
#ifndef _OBJFAC3D_HXX
#include <svx/objfac3d.hxx>
#endif

#pragma hdrstop

#include "sddll.hxx"
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "sdresid.hxx"
#include "sdobjfac.hxx"
#include "cfgids.hxx"
#include "strmname.h"
#include "SdShapeTypes.hxx"

#include <svx/SvxShapeTypes.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <tools/urlobj.hxx>
#include <svx/impgrf.hxx>
#include <svtools/FilterConfigItem.hxx>

#ifndef _COM_SUN_STAR_UTIL_XARCHIVER_HPP_
#include <com/sun/star/util/XArchiver.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

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

/*************************************************************************
|*
|* Init
|*
\************************************************************************/

void SdDLL::Init()
{
    if ( SD_MOD() )
        return;

    SfxObjectFactory* pDrawFact = NULL;
    SfxObjectFactory* pImpressFact = NULL;

    if (SvtModuleOptions().IsImpress())
        pImpressFact = &::sd::DrawDocShell::Factory();

    if (SvtModuleOptions().IsDraw())
        pDrawFact = &::sd::GraphicDocShell::Factory();

    // the SdModule must be created
     SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    (*ppShlPtr) = new SdModule( pImpressFact, pDrawFact);

    if (SvtModuleOptions().IsImpress())
    {
        // Register the Impress shape types in order to make the shapes accessible.
        ::accessibility::RegisterImpressShapeTypes ();
        ::sd::DrawDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) );
        ::sd::DrawDocShell::Factory().RegisterMenuBar( SdResId( RID_DRAW_DEFAULTMENU ) );
        ::sd::DrawDocShell::Factory().RegisterAccel( SdResId( RID_DRAW_DEFAULTACCEL ) );
    }

    if (SvtModuleOptions().IsDraw())
    {
        ::sd::GraphicDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) );
        ::sd::GraphicDocShell::Factory().RegisterMenuBar( SdResId( RID_GRAPHIC_DEFAULTMENU ) );
        ::sd::GraphicDocShell::Factory().RegisterAccel( SdResId( RID_GRAPHIC_DEFAULTACCEL ) );
    }

    // register your view-factories here
    RegisterFactorys();

    // register your shell-interfaces here
    RegisterInterfaces();

    // register your controllers here
    RegisterControllers();

    // SvDraw-Felder registrieren
    SdrRegisterFieldClasses();

    // 3D-Objekt-Factory eintragen
    E3dObjFactory();

    // ::com::sun::star::form::component::Form-Objekt-Factory eintragen
    FmFormObjFactory();

    // factory for dummy import of old si-controls in 3.1 documents
    SiImportFactory();

    // Objekt-Factory eintragen
    SdrObjFactory::InsertMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));
}

/*************************************************************************
|*
|* Exit
|*
\************************************************************************/

void SdDLL::Exit()
{
    // called directly befor unloading the DLL
    // do whatever you want, Sd-DLL is accessible

    // Objekt-Factory austragen
    SdrObjFactory::RemoveMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));

    // the SdModule must be destroyed
    SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    delete (*ppShlPtr);
    (*ppShlPtr) = NULL;
}

/*
ULONG SdDLL::DetectFilter(SfxMedium& rMedium, const SfxFilter** ppFilter,
                          SfxFilterFlags nMust, SfxFilterFlags nDont)
{
    ULONG nReturn = ERRCODE_ABORT;  // Erkennung fehlgeschlagen, Filter ungueltig
    BOOL bStorage = FALSE;

    if( *ppFilter && (*ppFilter)->GetFilterFlags() & SFX_FILTER_PACKED )
    {
        uno::Reference< lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() );
        uno::Reference< util::XArchiver > xPacker( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.util.Archiver" ) ), uno::UNO_QUERY );
        if( xPacker.is() )
        {
            // extract extra data
            OUString aPath( rMedium.GetOrigURL() );
            OUString aExtraData( xPacker->getExtraData( aPath ) );
            const OUString aSig1= OUString::createFromAscii( "private:" );
            String aTmp;
            aTmp += sal_Unicode( '?' );
            aTmp += String::CreateFromAscii("simpress");
            const OUString aSig2( aTmp );
            INT32 nIndex1 = aExtraData.indexOf( aSig1 );
            INT32 nIndex2 = aExtraData.indexOf( aSig2 );
            if( nIndex1 == 0 && nIndex2 != -1 )
                return ERRCODE_NONE;
        }
    }
    else if (rMedium.GetError() == SVSTREAM_OK)
    {
        if ( rMedium.IsStorage() )
        {
            bStorage = TRUE;
            SotStorageRef xStorage = rMedium.GetStorage();
            if ( !xStorage.Is() )
                return ULONG_MAX;

            if( SvtModuleOptions().IsImpress() )
            {
                // Erkennung ueber contained streams (PowerPoint 97-Filter)
                String aStreamName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) );
                if ( xStorage->IsContained( aStreamName ) && xStorage->IsStream( aStreamName ) )
                {
                    String aFileName(rMedium.GetName());
                    aFileName.ToUpperAscii();

                    if( aFileName.SearchAscii( ".POT" ) == STRING_NOTFOUND )
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97);
                    else
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97Template );

                    return ERRCODE_NONE;
                }
            }

            const SfxFilter* pFilter = *ppFilter;
            if ( *ppFilter )
            {
                if ( (*ppFilter)->GetFormat() == xStorage->GetFormat() )
                    pFilter = *ppFilter;
            }

             if( !pFilter && SvtModuleOptions().IsImpress() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("simpress") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if( !pFilter && SvtModuleOptions().IsDraw() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("sdraw") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if ( pFilter &&
                ( pFilter->GetFilterFlags() & nMust ) == nMust &&
                ( pFilter->GetFilterFlags() & nDont ) == 0 )
            {
                *ppFilter = pFilter;
                nReturn = ERRCODE_NONE;
            }
            else
            {
                *ppFilter = NULL;
                nReturn = ERRCODE_NONE;
            }
        }

        String aFileName( rMedium.GetName() );
        aFileName.ToUpperAscii();

        if ( nReturn == ERRCODE_ABORT )
        {
            if( bStorage )         // aber keine Clipboard-Id #55337#
            {
                *ppFilter = NULL;
            }
            else
            {
                // Vektorgraphik?
                SvStream* pStm = rMedium.GetInStream();

                if( !pStm )
                    nReturn = ERRCODE_IO_GENERAL;
                else
                {
                    pStm->Seek( STREAM_SEEK_TO_BEGIN );

                    const String        aFileName( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
                    GraphicDescriptor   aDesc( *pStm, &aFileName );
                    GraphicFilter*      pGrfFilter = GetGrfFilter();

                    if( !aDesc.Detect( FALSE ) )
                    {
                        if( SvtModuleOptions().IsImpress() )
                        {
                            *ppFilter = NULL;
                            nReturn = ERRCODE_ABORT;
                            INetURLObject aURL( aFileName );
                            if( aURL.getExtension().EqualsIgnoreCaseAscii( "cgm" ) )
                            {
                                sal_uInt8 n8;
                                pStm->Seek( STREAM_SEEK_TO_BEGIN );
                                *pStm >> n8;
                                if ( ( n8 & 0xf0 ) == 0 )       // we are supporting binary cgm format only, so
                                {                               // this is a small test to exclude cgm text
                                    const String aName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "CGM - Computer Graphics Metafile" ) );
                                    SfxFilterMatcher aMatch( String::CreateFromAscii("simpress") );
                                    *ppFilter = aMatch.GetFilter4FilterName( aName );
                                    nReturn = ERRCODE_NONE;
                                }
                            }
                        }
                    }
                    else
                    {
                        if( SvtModuleOptions().IsDraw() )
                        {
                            String aShortName( aDesc.GetImportFormatShortName( aDesc.GetFileFormat() ) );
                            const String aName( pGrfFilter->GetImportFormatTypeName( pGrfFilter->GetImportFormatNumberForShortName( aShortName ) ) );

                            if ( *ppFilter && aShortName.EqualsIgnoreCaseAscii( "PCD" ) )    // there is a multiple pcd selection possible
                            {
                                sal_Int32 nBase = 2;    // default Base0
                                String aFilterTypeName( (*ppFilter)->GetRealTypeName() );
                                if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base4" ) == COMPARE_EQUAL )
                                    nBase = 1;
                                else if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base16" ) == COMPARE_EQUAL )
                                    nBase = 0;
                                String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
                                FilterConfigItem aFilterConfigItem( aFilterConfigPath );
                                aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
                            }

                            SfxFilterMatcher aMatch( String::CreateFromAscii("draw") );
                            *ppFilter = aMatch.GetFilter4FilterName( aName );
                            nReturn = ERRCODE_NONE;
                        }
                        else
                        {
                            nReturn = ERRCODE_ABORT;
                            *ppFilter = NULL;
                        }
                    }
                }
            }
        }
    }
    else
    {
        nReturn = rMedium.GetError();
    }

    return nReturn;
} */
<commit_msg>INTEGRATION: CWS aw019 (1.7.214); FILE MERGED 2004/10/18 16:55:57 aw 1.7.214.2: RESYNC: (1.7-1.8); FILE MERGED 2004/09/29 14:30:14 aw 1.7.214.1: #i11190#<commit_after>/*************************************************************************
 *
 *  $RCSfile: sddll.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-11-03 08:54:36 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif

#include <svx/editeng.hxx>

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#ifndef _FM_FMOBJFAC_HXX
#include <svx/fmobjfac.hxx>
#endif
#ifndef _SVX_SIIMPORT_HXX
#include <svx/siimport.hxx>
#endif
#ifndef _SVDFIELD_HXX
#include <svx/svdfield.hxx>
#endif
#ifndef _OBJFAC3D_HXX
#include <svx/objfac3d.hxx>
#endif

#pragma hdrstop

#include "sddll.hxx"
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "sdresid.hxx"
#include "sdobjfac.hxx"
#include "cfgids.hxx"
#include "strmname.h"
#include "SdShapeTypes.hxx"

#include <svx/SvxShapeTypes.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <tools/urlobj.hxx>
#include <svx/impgrf.hxx>
#include <svtools/FilterConfigItem.hxx>

#ifndef _COM_SUN_STAR_UTIL_XARCHIVER_HPP_
#include <com/sun/star/util/XArchiver.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

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

/*************************************************************************
|*
|* Init
|*
\************************************************************************/

void SdDLL::Init()
{
    if ( SD_MOD() )
        return;

    SfxObjectFactory* pDrawFact = NULL;
    SfxObjectFactory* pImpressFact = NULL;

    if (SvtModuleOptions().IsImpress())
        pImpressFact = &::sd::DrawDocShell::Factory();

    if (SvtModuleOptions().IsDraw())
        pDrawFact = &::sd::GraphicDocShell::Factory();

    // the SdModule must be created
     SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    (*ppShlPtr) = new SdModule( pImpressFact, pDrawFact);

    if (SvtModuleOptions().IsImpress())
    {
        // Register the Impress shape types in order to make the shapes accessible.
        ::accessibility::RegisterImpressShapeTypes ();
        ::sd::DrawDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) );
        ::sd::DrawDocShell::Factory().RegisterMenuBar( SdResId( RID_DRAW_DEFAULTMENU ) );
        ::sd::DrawDocShell::Factory().RegisterAccel( SdResId( RID_DRAW_DEFAULTACCEL ) );
    }

    if (SvtModuleOptions().IsDraw())
    {
        ::sd::GraphicDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) );
        ::sd::GraphicDocShell::Factory().RegisterMenuBar( SdResId( RID_GRAPHIC_DEFAULTMENU ) );
        ::sd::GraphicDocShell::Factory().RegisterAccel( SdResId( RID_GRAPHIC_DEFAULTACCEL ) );
    }

    // register your view-factories here
    RegisterFactorys();

    // register your shell-interfaces here
    RegisterInterfaces();

    // register your controllers here
    RegisterControllers();

    // SvDraw-Felder registrieren
    SdrRegisterFieldClasses();

    // 3D-Objekt-Factory eintragen
    E3dObjFactory();

    // ::com::sun::star::form::component::Form-Objekt-Factory eintragen
    FmFormObjFactory();

    // factory for dummy import of old si-controls in 3.1 documents
//BFS02    SiImportFactory();

    // Objekt-Factory eintragen
    SdrObjFactory::InsertMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));
}

/*************************************************************************
|*
|* Exit
|*
\************************************************************************/

void SdDLL::Exit()
{
    // called directly befor unloading the DLL
    // do whatever you want, Sd-DLL is accessible

    // Objekt-Factory austragen
    SdrObjFactory::RemoveMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));

    // the SdModule must be destroyed
    SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    delete (*ppShlPtr);
    (*ppShlPtr) = NULL;
}

/*
ULONG SdDLL::DetectFilter(SfxMedium& rMedium, const SfxFilter** ppFilter,
                          SfxFilterFlags nMust, SfxFilterFlags nDont)
{
    ULONG nReturn = ERRCODE_ABORT;  // Erkennung fehlgeschlagen, Filter ungueltig
    BOOL bStorage = FALSE;

    if( *ppFilter && (*ppFilter)->GetFilterFlags() & SFX_FILTER_PACKED )
    {
        uno::Reference< lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() );
        uno::Reference< util::XArchiver > xPacker( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.util.Archiver" ) ), uno::UNO_QUERY );
        if( xPacker.is() )
        {
            // extract extra data
            OUString aPath( rMedium.GetOrigURL() );
            OUString aExtraData( xPacker->getExtraData( aPath ) );
            const OUString aSig1= OUString::createFromAscii( "private:" );
            String aTmp;
            aTmp += sal_Unicode( '?' );
            aTmp += String::CreateFromAscii("simpress");
            const OUString aSig2( aTmp );
            INT32 nIndex1 = aExtraData.indexOf( aSig1 );
            INT32 nIndex2 = aExtraData.indexOf( aSig2 );
            if( nIndex1 == 0 && nIndex2 != -1 )
                return ERRCODE_NONE;
        }
    }
    else if (rMedium.GetError() == SVSTREAM_OK)
    {
        if ( rMedium.IsStorage() )
        {
            bStorage = TRUE;
            SotStorageRef xStorage = rMedium.GetStorage();
            if ( !xStorage.Is() )
                return ULONG_MAX;

            if( SvtModuleOptions().IsImpress() )
            {
                // Erkennung ueber contained streams (PowerPoint 97-Filter)
                String aStreamName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) );
                if ( xStorage->IsContained( aStreamName ) && xStorage->IsStream( aStreamName ) )
                {
                    String aFileName(rMedium.GetName());
                    aFileName.ToUpperAscii();

                    if( aFileName.SearchAscii( ".POT" ) == STRING_NOTFOUND )
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97);
                    else
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97Template );

                    return ERRCODE_NONE;
                }
            }

            const SfxFilter* pFilter = *ppFilter;
            if ( *ppFilter )
            {
                if ( (*ppFilter)->GetFormat() == xStorage->GetFormat() )
                    pFilter = *ppFilter;
            }

             if( !pFilter && SvtModuleOptions().IsImpress() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("simpress") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if( !pFilter && SvtModuleOptions().IsDraw() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("sdraw") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if ( pFilter &&
                ( pFilter->GetFilterFlags() & nMust ) == nMust &&
                ( pFilter->GetFilterFlags() & nDont ) == 0 )
            {
                *ppFilter = pFilter;
                nReturn = ERRCODE_NONE;
            }
            else
            {
                *ppFilter = NULL;
                nReturn = ERRCODE_NONE;
            }
        }

        String aFileName( rMedium.GetName() );
        aFileName.ToUpperAscii();

        if ( nReturn == ERRCODE_ABORT )
        {
            if( bStorage )         // aber keine Clipboard-Id #55337#
            {
                *ppFilter = NULL;
            }
            else
            {
                // Vektorgraphik?
                SvStream* pStm = rMedium.GetInStream();

                if( !pStm )
                    nReturn = ERRCODE_IO_GENERAL;
                else
                {
                    pStm->Seek( STREAM_SEEK_TO_BEGIN );

                    const String        aFileName( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
                    GraphicDescriptor   aDesc( *pStm, &aFileName );
                    GraphicFilter*      pGrfFilter = GetGrfFilter();

                    if( !aDesc.Detect( FALSE ) )
                    {
                        if( SvtModuleOptions().IsImpress() )
                        {
                            *ppFilter = NULL;
                            nReturn = ERRCODE_ABORT;
                            INetURLObject aURL( aFileName );
                            if( aURL.getExtension().EqualsIgnoreCaseAscii( "cgm" ) )
                            {
                                sal_uInt8 n8;
                                pStm->Seek( STREAM_SEEK_TO_BEGIN );
                                *pStm >> n8;
                                if ( ( n8 & 0xf0 ) == 0 )       // we are supporting binary cgm format only, so
                                {                               // this is a small test to exclude cgm text
                                    const String aName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "CGM - Computer Graphics Metafile" ) );
                                    SfxFilterMatcher aMatch( String::CreateFromAscii("simpress") );
                                    *ppFilter = aMatch.GetFilter4FilterName( aName );
                                    nReturn = ERRCODE_NONE;
                                }
                            }
                        }
                    }
                    else
                    {
                        if( SvtModuleOptions().IsDraw() )
                        {
                            String aShortName( aDesc.GetImportFormatShortName( aDesc.GetFileFormat() ) );
                            const String aName( pGrfFilter->GetImportFormatTypeName( pGrfFilter->GetImportFormatNumberForShortName( aShortName ) ) );

                            if ( *ppFilter && aShortName.EqualsIgnoreCaseAscii( "PCD" ) )    // there is a multiple pcd selection possible
                            {
                                sal_Int32 nBase = 2;    // default Base0
                                String aFilterTypeName( (*ppFilter)->GetRealTypeName() );
                                if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base4" ) == COMPARE_EQUAL )
                                    nBase = 1;
                                else if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base16" ) == COMPARE_EQUAL )
                                    nBase = 0;
                                String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
                                FilterConfigItem aFilterConfigItem( aFilterConfigPath );
                                aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
                            }

                            SfxFilterMatcher aMatch( String::CreateFromAscii("draw") );
                            *ppFilter = aMatch.GetFilter4FilterName( aName );
                            nReturn = ERRCODE_NONE;
                        }
                        else
                        {
                            nReturn = ERRCODE_ABORT;
                            *ppFilter = NULL;
                        }
                    }
                }
            }
        }
    }
    else
    {
        nReturn = rMedium.GetError();
    }

    return nReturn;
} */
<|endoftext|>


<commit_before>// Why?
#define _WIN32_WINNT 0x0502
// The standard Windows includes.
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <shellapi.h>
#include <wchar.h>
// Let the NVIDIA and AMD know we want to use their graphics card
// on a dual graphics card system.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;

#include <stdlib.h>
#include <stdio.h>
#include <GL/GL.h>

#include <string>
#include <vector>

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <stdio.h>

class OpenGLVersionCheck
{
public:
	std::string version;
	std::string glsl_version;
	std::string vendor;
	std::string renderer;

	HINSTANCE   hOpenGL = nullptr;
	bool 		success = false;

	bool load_opengl_dll()
	{
	    MSG      msg     = {0};
	    WNDCLASS wc      = {0};
	    wc.lpfnWndProc   = OpenGLVersionCheck::supports_opengl2_wndproc;
	    wc.hInstance     = (HINSTANCE)GetModuleHandle(nullptr);
	    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
	    wc.lpszClassName = L"slic3r_opengl_version_check";
	    wc.style = CS_OWNDC;
	    if (RegisterClass(&wc)) {
			HWND hwnd = CreateWindowW(wc.lpszClassName, L"slic3r_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
			if (hwnd) {
				message_pump_exit = false;
			    while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
			        DispatchMessage(&msg);
			}
		}
	    return this->success;
	}

	void unload_opengl_dll()
	{
		if (this->hOpenGL) {
			BOOL released = FreeLibrary(this->hOpenGL);
			if (released)
				printf("System OpenGL library released\n");
			else
				printf("System OpenGL library NOT released\n");
			this->hOpenGL = nullptr;
		}
	}

	bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
	{
		// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
	    std::vector<std::string> tokens;
	    boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
	    if (tokens.empty())
	        return false;

	    std::vector<std::string> numbers;
	    boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);

	    unsigned int gl_major = 0;
	    unsigned int gl_minor = 0;
	    if (numbers.size() > 0)
	        gl_major = ::atoi(numbers[0].c_str());
	    if (numbers.size() > 1)
	        gl_minor = ::atoi(numbers[1].c_str());
	    // printf("Major: %d, minor: %d\n", gl_major, gl_minor);
	    if (gl_major < major)
	        return false;
	    else if (gl_major > major)
	        return true;
	    else
	        return gl_minor >= minor;
	}

protected:
	static bool message_pump_exit;

	void check(HWND hWnd)
	{
		hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
		if (hOpenGL == nullptr) {
			printf("Failed loading the system opengl32.dll\n");
			return;
		}

		typedef HGLRC 		(WINAPI *Func_wglCreateContext)(HDC);
		typedef BOOL 		(WINAPI *Func_wglMakeCurrent  )(HDC, HGLRC);
		typedef BOOL     	(WINAPI *Func_wglDeleteContext)(HGLRC);
		typedef GLubyte* 	(WINAPI *Func_glGetString     )(GLenum);

		Func_wglCreateContext 	wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
		Func_wglMakeCurrent 	wglMakeCurrent 	 = (Func_wglMakeCurrent)  GetProcAddress(hOpenGL, "wglMakeCurrent");
		Func_wglDeleteContext 	wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
		Func_glGetString 		glGetString 	 = (Func_glGetString)	  GetProcAddress(hOpenGL, "glGetString");

		if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
			printf("Failed loading the system opengl32.dll: The library is invalid.\n");
			return;
		}

        PIXELFORMATDESCRIPTOR pfd =
        {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,            	// The kind of framebuffer. RGBA or palette.
            32,                        	// Color depth of the framebuffer.
            0, 0, 0, 0, 0, 0,
            0,
            0,
            0,
            0, 0, 0, 0,
            24,                        	// Number of bits for the depthbuffer
            8,                        	// Number of bits for the stencilbuffer
            0,                        	// Number of Aux buffers in the framebuffer.
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
        };

        HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
		// Gdi32.dll
        int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
		// Gdi32.dll
        SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
		// Opengl32.dll
        HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
        wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
        // Opengl32.dll
	    const char *data = (const char*)glGetString(GL_VERSION);
	    if (data != nullptr)
	        this->version = data;
		// printf("check -version: %s\n", version.c_str());
		data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
    	if (data != nullptr)
        	this->glsl_version = data;
    	data = (const char*)glGetString(GL_VENDOR);
    	if (data != nullptr)
        	this->vendor = data;
    	data = (const char*)glGetString(GL_RENDERER);
    	if (data != nullptr)
        	this->renderer = data;
        // Opengl32.dll
        wglDeleteContext(glcontext);
		::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
        this->success = true;
	}

	static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
	    switch(message)
	    {
	    case WM_CREATE:
		{
			CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
			OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
			ogl_data->check(hWnd);
			DestroyWindow(hWnd);
			return 0;
	    }
		case WM_NCDESTROY:
			message_pump_exit = true;
			return 0;
	    default:
	        return DefWindowProc(hWnd, message, wParam, lParam);
	    }
	}
};

bool OpenGLVersionCheck::message_pump_exit = false;

extern "C" {
	typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv);
	Slic3rMainFunc slic3r_main = nullptr;
}

#ifdef SLIC3R_WRAPPER_NOCONSOLE
int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */)
{
	int 	  argc;
	wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
#else
int wmain(int argc, wchar_t **argv)
{
#endif

	std::vector<wchar_t*> argv_extended;
	argv_extended.emplace_back(argv[0]);
	// Here one may push some additional parameters based on the wrapper type.
	for (int i = 1; i < argc; ++ i)
		argv_extended.emplace_back(argv[i]);
	argv_extended.emplace_back(nullptr);

	OpenGLVersionCheck opengl_version_check;
	bool load_mesa = ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0);

	wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
	::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
	wchar_t drive[_MAX_DRIVE];
	wchar_t dir[_MAX_DIR];
	wchar_t fname[_MAX_FNAME];
	wchar_t ext[_MAX_EXT];
	_wsplitpath(path_to_exe, drive, dir, fname, ext);
	_wmakepath(path_to_exe, drive, dir, nullptr, nullptr);

// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
	if (load_mesa) {
		opengl_version_check.unload_opengl_dll();
		wchar_t path_to_mesa[MAX_PATH + 1] = { 0 };
		wcscpy(path_to_mesa, path_to_exe);
		wcscat(path_to_mesa, L"mesa\\opengl32.dll");
		printf("Loading MESA OpenGL library: %S\n", path_to_mesa);
		HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
		if (hInstance_OpenGL == nullptr) {
			printf("MESA OpenGL library was not loaded\n");
		} else
			printf("MESA OpenGL library was loaded sucessfully\n");
	}

	wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 };
	wcscpy(path_to_slic3r, path_to_exe);
	wcscat(path_to_slic3r, L"slic3r.dll");
//	printf("Loading Slic3r library: %S\n", path_to_slic3r);
	HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0);
	if (hInstance_Slic3r == nullptr) {
		printf("slic3r.dll was not loaded\n");
		return -1;
	}

	// resolve function address here
	slic3r_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r,
#ifdef _WIN64
		// there is just a single calling conversion, therefore no mangling of the function name.
		"slic3r_main"
#else	// stdcall calling convention declaration
		"_slic3r_main@8"
#endif
		);
	if (slic3r_main == nullptr) {
		printf("could not locate the function slic3r_main in slic3r.dll\n");
		return -1;
	}
	// argc minus the trailing nullptr of the argv
	return slic3r_main(argv_extended.size() - 1, argv_extended.data());
}
<commit_msg>Detect Remote Desktop connection and use Mesa OpenGL renderer.<commit_after>// Why?
#define _WIN32_WINNT 0x0502
// The standard Windows includes.
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <shellapi.h>
#include <wchar.h>
// Let the NVIDIA and AMD know we want to use their graphics card
// on a dual graphics card system.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;

#include <stdlib.h>
#include <stdio.h>
#include <GL/GL.h>

#include <string>
#include <vector>

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <stdio.h>

class OpenGLVersionCheck
{
public:
	std::string version;
	std::string glsl_version;
	std::string vendor;
	std::string renderer;

	HINSTANCE   hOpenGL = nullptr;
	bool 		success = false;

	bool load_opengl_dll()
	{
	    MSG      msg     = {0};
	    WNDCLASS wc      = {0};
	    wc.lpfnWndProc   = OpenGLVersionCheck::supports_opengl2_wndproc;
	    wc.hInstance     = (HINSTANCE)GetModuleHandle(nullptr);
	    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
	    wc.lpszClassName = L"slic3r_opengl_version_check";
	    wc.style = CS_OWNDC;
	    if (RegisterClass(&wc)) {
			HWND hwnd = CreateWindowW(wc.lpszClassName, L"slic3r_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
			if (hwnd) {
				message_pump_exit = false;
			    while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
			        DispatchMessage(&msg);
			}
		}
	    return this->success;
	}

	void unload_opengl_dll()
	{
		if (this->hOpenGL) {
			BOOL released = FreeLibrary(this->hOpenGL);
			if (released)
				printf("System OpenGL library released\n");
			else
				printf("System OpenGL library NOT released\n");
			this->hOpenGL = nullptr;
		}
	}

	bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
	{
		// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
	    std::vector<std::string> tokens;
	    boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
	    if (tokens.empty())
	        return false;

	    std::vector<std::string> numbers;
	    boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);

	    unsigned int gl_major = 0;
	    unsigned int gl_minor = 0;
	    if (numbers.size() > 0)
	        gl_major = ::atoi(numbers[0].c_str());
	    if (numbers.size() > 1)
	        gl_minor = ::atoi(numbers[1].c_str());
	    // printf("Major: %d, minor: %d\n", gl_major, gl_minor);
	    if (gl_major < major)
	        return false;
	    else if (gl_major > major)
	        return true;
	    else
	        return gl_minor >= minor;
	}

protected:
	static bool message_pump_exit;

	void check(HWND hWnd)
	{
		hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
		if (hOpenGL == nullptr) {
			printf("Failed loading the system opengl32.dll\n");
			return;
		}

		typedef HGLRC 		(WINAPI *Func_wglCreateContext)(HDC);
		typedef BOOL 		(WINAPI *Func_wglMakeCurrent  )(HDC, HGLRC);
		typedef BOOL     	(WINAPI *Func_wglDeleteContext)(HGLRC);
		typedef GLubyte* 	(WINAPI *Func_glGetString     )(GLenum);

		Func_wglCreateContext 	wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
		Func_wglMakeCurrent 	wglMakeCurrent 	 = (Func_wglMakeCurrent)  GetProcAddress(hOpenGL, "wglMakeCurrent");
		Func_wglDeleteContext 	wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
		Func_glGetString 		glGetString 	 = (Func_glGetString)	  GetProcAddress(hOpenGL, "glGetString");

		if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
			printf("Failed loading the system opengl32.dll: The library is invalid.\n");
			return;
		}

        PIXELFORMATDESCRIPTOR pfd =
        {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,            	// The kind of framebuffer. RGBA or palette.
            32,                        	// Color depth of the framebuffer.
            0, 0, 0, 0, 0, 0,
            0,
            0,
            0,
            0, 0, 0, 0,
            24,                        	// Number of bits for the depthbuffer
            8,                        	// Number of bits for the stencilbuffer
            0,                        	// Number of Aux buffers in the framebuffer.
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
        };

        HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
		// Gdi32.dll
        int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
		// Gdi32.dll
        SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
		// Opengl32.dll
        HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
        wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
        // Opengl32.dll
	    const char *data = (const char*)glGetString(GL_VERSION);
	    if (data != nullptr)
	        this->version = data;
		// printf("check -version: %s\n", version.c_str());
		data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
    	if (data != nullptr)
        	this->glsl_version = data;
    	data = (const char*)glGetString(GL_VENDOR);
    	if (data != nullptr)
        	this->vendor = data;
    	data = (const char*)glGetString(GL_RENDERER);
    	if (data != nullptr)
        	this->renderer = data;
        // Opengl32.dll
        wglDeleteContext(glcontext);
		::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
        this->success = true;
	}

	static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
	    switch(message)
	    {
	    case WM_CREATE:
		{
			CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
			OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
			ogl_data->check(hWnd);
			DestroyWindow(hWnd);
			return 0;
	    }
		case WM_NCDESTROY:
			message_pump_exit = true;
			return 0;
	    default:
	        return DefWindowProc(hWnd, message, wParam, lParam);
	    }
	}
};

bool OpenGLVersionCheck::message_pump_exit = false;

extern "C" {
	typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv);
	Slic3rMainFunc slic3r_main = nullptr;
}

#ifdef SLIC3R_WRAPPER_NOCONSOLE
int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */)
{
	int 	  argc;
	wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
#else
int wmain(int argc, wchar_t **argv)
{
#endif

	std::vector<wchar_t*> argv_extended;
	argv_extended.emplace_back(argv[0]);
	// Here one may push some additional parameters based on the wrapper type.
	for (int i = 1; i < argc; ++ i)
		argv_extended.emplace_back(argv[i]);
	argv_extended.emplace_back(nullptr);

	OpenGLVersionCheck opengl_version_check;
	bool load_mesa =
		// Running over a rempote desktop, and the RemoteFX is not enabled, therefore Windows will only provide SW OpenGL 1.1 context.
		// In that case, use Mesa.
		::GetSystemMetrics(SM_REMOTESESSION) ||
		// Try to load the default OpenGL driver and test its context version.
		! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0);

	wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
	::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
	wchar_t drive[_MAX_DRIVE];
	wchar_t dir[_MAX_DIR];
	wchar_t fname[_MAX_FNAME];
	wchar_t ext[_MAX_EXT];
	_wsplitpath(path_to_exe, drive, dir, fname, ext);
	_wmakepath(path_to_exe, drive, dir, nullptr, nullptr);

// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
	if (load_mesa) {
		opengl_version_check.unload_opengl_dll();
		wchar_t path_to_mesa[MAX_PATH + 1] = { 0 };
		wcscpy(path_to_mesa, path_to_exe);
		wcscat(path_to_mesa, L"mesa\\opengl32.dll");
		printf("Loading MESA OpenGL library: %S\n", path_to_mesa);
		HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
		if (hInstance_OpenGL == nullptr) {
			printf("MESA OpenGL library was not loaded\n");
		} else
			printf("MESA OpenGL library was loaded sucessfully\n");
	}

	wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 };
	wcscpy(path_to_slic3r, path_to_exe);
	wcscat(path_to_slic3r, L"slic3r.dll");
//	printf("Loading Slic3r library: %S\n", path_to_slic3r);
	HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0);
	if (hInstance_Slic3r == nullptr) {
		printf("slic3r.dll was not loaded\n");
		return -1;
	}

	// resolve function address here
	slic3r_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r,
#ifdef _WIN64
		// there is just a single calling conversion, therefore no mangling of the function name.
		"slic3r_main"
#else	// stdcall calling convention declaration
		"_slic3r_main@8"
#endif
		);
	if (slic3r_main == nullptr) {
		printf("could not locate the function slic3r_main in slic3r.dll\n");
		return -1;
	}
	// argc minus the trailing nullptr of the argv
	return slic3r_main(argv_extended.size() - 1, argv_extended.data());
}
<|endoftext|>


<commit_before>#include "criterion.h"
#include "task.h"
#include "loss.h"
#include <cassert>

namespace ncv
{
        criterion_t::criterion_t(const string_t& configuration)
                :       clonable_t<criterion_t>(configuration),
                        m_lambda(0.0),
                        m_type(type::value)
        {
        }

        criterion_t& criterion_t::reset(const rmodel_t& rmodel)
        {
                assert(rmodel);
                return reset(*rmodel);
        }

        criterion_t& criterion_t::reset(const model_t& model)
        {
                m_model = model.clone();
                m_model->save_params(m_params);
                m_estats.clear();

                reset();

                return *this;
        }

        criterion_t& criterion_t::reset(const vector_t& params)
        {
                assert(m_model->psize() == static_cast<size_t>(params.size()));

                m_model->load_params(params);
                m_params = params;
                m_estats.clear();

                reset();

                return *this;
        }

        criterion_t& criterion_t::reset(type t)
        {
                m_type = t;
                return *this;
        }

        criterion_t& criterion_t::reset(scalar_t lambda)
        {
                m_lambda = lambda;
                return *this;
        }

        void criterion_t::update(const task_t& task, const sample_t& sample, const loss_t& loss)
        {
                assert(sample.m_index < task.n_images());

                const image_t& image = task.image(sample.m_index);
                const vector_t& target = sample.m_target;
                const vector_t& output = m_model->output(image, sample.m_region).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());
        }

        void criterion_t::update(const tensor_t& input, const vector_t& target, const loss_t& loss)
        {
                const vector_t& output = m_model->output(input).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());

                accumulate(output, target, loss);
        }

        void criterion_t::update(const vector_t& input, const vector_t& target, const loss_t& loss)
        {
                const vector_t& output = m_model->output(input).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());

                accumulate(output, target, loss);
        }

        void criterion_t::accumulate(const vector_t& output, const vector_t& target, const loss_t& loss)
        {
                const scalar_t value = loss.value(target, output);
                const scalar_t error = loss.error(target, output);

                m_estats(error);

                switch (m_type)
                {
                case type::value:
                        accumulate(value, error);
                        break;

                case type::vgrad:
                        accumulate(m_model->gparam(loss.vgrad(target, output)), value, error);
                        break;
                }
        }

        criterion_t& criterion_t::operator+=(const criterion_t& other)
        {
                m_estats(other.m_estats);

                accumulate(other);

                return *this;
        }

        scalar_t criterion_t::avg_error() const
        {
                assert(m_estats.count() > 0);

                return m_estats.avg();
        }

        scalar_t criterion_t::var_error() const
        {
                assert(m_estats.count() > 0);

                return m_estats.var();
        }

        size_t criterion_t::count() const
        {
                return m_estats.count();
        }

        const vector_t& criterion_t::params() const
        {
                return m_params;
        }

        size_t criterion_t::psize() const
        {
                return static_cast<size_t>(m_params.size());
        }

        scalar_t criterion_t::lambda() const
        {
                return m_lambda;
        }
}

<commit_msg>fix acumulator<commit_after>#include "criterion.h"
#include "task.h"
#include "loss.h"
#include <cassert>

namespace ncv
{
        criterion_t::criterion_t(const string_t& configuration)
                :       clonable_t<criterion_t>(configuration),
                        m_lambda(0.0),
                        m_type(type::value)
        {
        }

        criterion_t& criterion_t::reset(const rmodel_t& rmodel)
        {
                assert(rmodel);
                return reset(*rmodel);
        }

        criterion_t& criterion_t::reset(const model_t& model)
        {
                m_model = model.clone();
                m_model->save_params(m_params);
                m_estats.clear();

                reset();

                return *this;
        }

        criterion_t& criterion_t::reset(const vector_t& params)
        {
                assert(m_model->psize() == static_cast<size_t>(params.size()));

                m_model->load_params(params);
                m_params = params;
                m_estats.clear();

                reset();

                return *this;
        }

        criterion_t& criterion_t::reset(type t)
        {
                m_type = t;
                return *this;
        }

        criterion_t& criterion_t::reset(scalar_t lambda)
        {
                m_lambda = lambda;
                return *this;
        }

        void criterion_t::update(const task_t& task, const sample_t& sample, const loss_t& loss)
        {
                assert(sample.m_index < task.n_images());

                const image_t& image = task.image(sample.m_index);
                const vector_t& target = sample.m_target;
                const vector_t& output = m_model->output(image, sample.m_region).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());

                accumulate(output, target, loss);
        }

        void criterion_t::update(const tensor_t& input, const vector_t& target, const loss_t& loss)
        {
                const vector_t& output = m_model->output(input).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());

                accumulate(output, target, loss);
        }

        void criterion_t::update(const vector_t& input, const vector_t& target, const loss_t& loss)
        {
                const vector_t& output = m_model->output(input).vector();

                assert(static_cast<size_t>(output.size()) == m_model->osize());
                assert(static_cast<size_t>(target.size()) == m_model->osize());

                accumulate(output, target, loss);
        }

        void criterion_t::accumulate(const vector_t& output, const vector_t& target, const loss_t& loss)
        {
                const scalar_t value = loss.value(target, output);
                const scalar_t error = loss.error(target, output);

                m_estats(error);

                switch (m_type)
                {
                case type::value:
                        accumulate(value, error);
                        break;

                case type::vgrad:
                        accumulate(m_model->gparam(loss.vgrad(target, output)), value, error);
                        break;
                }
        }

        criterion_t& criterion_t::operator+=(const criterion_t& other)
        {
                m_estats(other.m_estats);

                accumulate(other);

                return *this;
        }

        scalar_t criterion_t::avg_error() const
        {
                assert(m_estats.count() > 0);

                return m_estats.avg();
        }

        scalar_t criterion_t::var_error() const
        {
                assert(m_estats.count() > 0);

                return m_estats.var();
        }

        size_t criterion_t::count() const
        {
                return m_estats.count();
        }

        const vector_t& criterion_t::params() const
        {
                return m_params;
        }

        size_t criterion_t::psize() const
        {
                return static_cast<size_t>(m_params.size());
        }

        scalar_t criterion_t::lambda() const
        {
                return m_lambda;
        }
}

<|endoftext|>


<commit_before>//---------------------------------------------------------
// Copyright 2017 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//
// nanopolish index - build an index from FASTA/FASTQ file
// and the associated signal-level data
//
//---------------------------------------------------------
//

//
// Getopt
//
#define SUBPROGRAM "index"

#include <iostream>
#include <fstream>
#include <sstream>
#include <getopt.h>

#include <fast5.hpp>
#include "nanopolish_index.h"
#include "nanopolish_common.h"
#include "nanopolish_read_db.h"
#include "fs_support.hpp"
#include "logger.hpp"
#include "profiler.h"
#include "nanopolish_fast5_io.h"

static const char *INDEX_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2017 Ontario Institute for Cancer Research\n";

static const char *INDEX_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " [OPTIONS] -d nanopore_raw_file_directory reads.fastq\n"
"Build an index mapping from basecalled reads to the signals measured by the sequencer\n"
"\n"
"      --help                           display this help and exit\n"
"      --version                        display version\n"
"  -v, --verbose                        display verbose output\n"
"  -d, --directory                      path to the directory containing the raw ONT signal files. This option can be given multiple times.\n"
"  -s, --sequencing-summary             the sequencing summary file from albacore, providing this option will make indexing much faster\n"
"  -f, --summary-fofn                   file containing the paths to the sequencing summary files (one per line)\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose = 0;
    static std::vector<std::string> raw_file_directories;
    static std::string reads_file;
    static std::vector<std::string> sequencing_summary_files;
    static std::string sequencing_summary_fofn;
}
static std::ostream* os_p;

//
void index_file_from_map(ReadDB& read_db, const std::string& fn, const std::multimap<std::string, std::string>& fast5_to_read_name_map)
{
    PROFILE_FUNC("index_file_from_map")

    // Check if this fast5 file is in the map
    size_t last_dir_pos = fn.find_last_of("/");
    std::string fast5_basename = last_dir_pos == std::string::npos ? fn : fn.substr(last_dir_pos + 1);

    auto range = fast5_to_read_name_map.equal_range(fast5_basename);
    for(auto iter = range.first; iter != range.second; ++iter) {
        if(read_db.has_read(iter->second)) {
            read_db.add_signal_path(iter->second.c_str(), fn);
        }
    }
}

//
void index_file_from_fast5(ReadDB& read_db, const std::string& fn)
{
    PROFILE_FUNC("index_file_from_fast5")

    fast5_file f5_file = fast5_open(fn);
    if(!fast5_is_open(f5_file)) {
        fprintf(stderr, "could not open fast5 file: %s\n", fn.c_str());
    }

    if(f5_file.is_multi_fast5) {
        std::vector<std::string> read_groups = fast5_get_multi_read_groups(f5_file);
        std::string prefix = "read_";
        for(size_t group_idx = 0; group_idx < read_groups.size(); ++group_idx) {
            std::string group_name = read_groups[group_idx];
            if(group_name.find(prefix) == 0) {
                std::string read_id = group_name.substr(prefix.size());
                read_db.add_signal_path(read_id, fn);
            }
        }
    } else {
        std::string read_id = fast5_get_read_id_single_fast5(f5_file);
        if(read_id != "") {
            read_db.add_signal_path(read_id, fn);
        }
    }
    fast5_close(f5_file);
}

//
void index_path(ReadDB& read_db, const std::string& path, const std::multimap<std::string, std::string>& fast5_to_read_name_map)
{
    fprintf(stderr, "[readdb] indexing %s\n", path.c_str());
    if (is_directory(path)) {
        auto dir_list = list_directory(path);
        for (const auto& fn : dir_list) {
            if(fn == "." or fn == "..") {
                continue;
            }

            std::string full_fn = path + "/" + fn;
            if(is_directory(full_fn)) {
                // recurse
                index_path(read_db, full_fn, fast5_to_read_name_map);
            } else if (full_fn.find(".fast5") != -1) {
                if(!fast5_to_read_name_map.empty()) {
                    index_file_from_map(read_db, full_fn, fast5_to_read_name_map);
                } else {
                    index_file_from_fast5(read_db, full_fn);
                }
            }
        }
    }
}

// read sequencing summary files from the fofn and add them to the list
void process_summary_fofn()
{
    if(opt::sequencing_summary_fofn.empty()) {
        return;
    }

    // open
    std::ifstream in_file(opt::sequencing_summary_fofn.c_str());
    if(in_file.bad()) {
        fprintf(stderr, "error: could not file %s\n", opt::sequencing_summary_fofn.c_str());
        exit(EXIT_FAILURE);
    }

    // read
    std::string filename;
    while(getline(in_file, filename)) {
        opt::sequencing_summary_files.push_back(filename);
    }
}

//
void exit_bad_header(const std::string& str, const std::string& filename)
{
    fprintf(stderr, "Could not find %s column in the header of %s\n", str.c_str(), filename.c_str());
    exit(EXIT_FAILURE);
}

//
void parse_sequencing_summary(const std::string& filename, std::multimap<std::string, std::string>& out_map)
{
    // open
    std::ifstream in_file(filename.c_str());
    if(!in_file.good()) {
        fprintf(stderr, "error: could not read file %s\n", filename.c_str());
        exit(EXIT_FAILURE);
    }

    // read header to get the column index of the read and file name
    std::string header;
    getline(in_file, header);
    std::vector<std::string> fields = split(header, '\t');

    const std::string READ_NAME_STR = "read_id";
    const std::string FILENAME_STR = "filename";
    size_t filename_idx = -1;
    size_t read_name_idx = -1;

    for(size_t i = 0; i < fields.size(); ++i) {
        if(fields[i] == READ_NAME_STR) {
            read_name_idx = i;
        }

        if(fields[i] == FILENAME_STR) {
            filename_idx = i;
        }
    }

    if(filename_idx == -1) {
        exit_bad_header(FILENAME_STR, filename);
    }

    if(read_name_idx == -1) {
        exit_bad_header(READ_NAME_STR, filename);
    }

    // read records and add to map
    std::string line;
    while(getline(in_file, line)) {
        fields = split(line, '\t');
        std::string fast5_filename = fields[filename_idx];
        std::string read_name = fields[read_name_idx];
        out_map.insert(std::make_pair(fast5_filename, read_name));
    }
}

static const char* shortopts = "vd:f:s:";

enum {
    OPT_HELP = 1,
    OPT_VERSION,
    OPT_LOG_LEVEL,
};

static const struct option longopts[] = {
    { "help",                      no_argument,       NULL, OPT_HELP },
    { "version",                   no_argument,       NULL, OPT_VERSION },
    { "log-level",                 required_argument, NULL, OPT_LOG_LEVEL },
    { "verbose",                   no_argument,       NULL, 'v' },
    { "directory",                 required_argument, NULL, 'd' },
    { "sequencing-summary-file",   required_argument, NULL, 's' },
    { "summary-fofn",              required_argument, NULL, 'f' },
    { NULL, 0, NULL, 0 }
};

void parse_index_options(int argc, char** argv)
{
    bool die = false;
    std::vector< std::string> log_level;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case OPT_HELP:
                std::cout << INDEX_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << INDEX_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_LOG_LEVEL:
                log_level.push_back(arg.str());
                break;
            case 'v': opt::verbose++; break;
            case 's': opt::sequencing_summary_files.push_back(arg.str()); break;
            case 'd': opt::raw_file_directories.push_back(arg.str()); break;
            case 'f': arg >> opt::sequencing_summary_fofn; break;
        }
    }

    // set log levels
    auto default_level = (int)logger::warning + opt::verbose;
    logger::Logger::set_default_level(default_level);
    logger::Logger::set_levels_from_options(log_level, &std::clog);

    if (argc - optind < 1) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (argc - optind > 1) {
        std::cerr << SUBPROGRAM ": too many arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << INDEX_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    opt::reads_file = argv[optind++];
}

int index_main(int argc, char** argv)
{
    parse_index_options(argc, argv);

    // Read a map from fast5 files to read name from the sequencing summary files (if any)
    process_summary_fofn();
    std::multimap<std::string, std::string> fast5_to_read_name_map;
    for(const auto& ss_filename : opt::sequencing_summary_files) {
        if(opt::verbose > 2) {
            fprintf(stderr, "summary: %s\n", ss_filename.c_str());
        }
        parse_sequencing_summary(ss_filename, fast5_to_read_name_map);
    }

    // import read names, and possibly fast5 paths, from the fasta/fastq file
    ReadDB read_db;
    read_db.build(opt::reads_file);
    bool all_reads_have_paths = read_db.check_signal_paths();

    // if the input fastq did not contain a complete set of paths
    // use the fofn/directory provided to augment the index
    if(!all_reads_have_paths) {

        for(const auto& dir_name : opt::raw_file_directories) {
            index_path(read_db, dir_name, fast5_to_read_name_map);
        }
    }

    size_t num_with_path = read_db.get_num_reads_with_path();
    if(num_with_path == 0) {
        fprintf(stderr, "Error: no fast5 files found\n");
        exit(EXIT_FAILURE);
    } else {
        read_db.print_stats();
        read_db.save();
    }
    return 0;
}
<commit_msg>optimize nanopolish index by skipping directory check when a read is in the map<commit_after>//---------------------------------------------------------
// Copyright 2017 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//
// nanopolish index - build an index from FASTA/FASTQ file
// and the associated signal-level data
//
//---------------------------------------------------------
//

//
// Getopt
//
#define SUBPROGRAM "index"

#include <iostream>
#include <fstream>
#include <sstream>
#include <getopt.h>

#include <fast5.hpp>
#include "nanopolish_index.h"
#include "nanopolish_common.h"
#include "nanopolish_read_db.h"
#include "fs_support.hpp"
#include "logger.hpp"
#include "profiler.h"
#include "nanopolish_fast5_io.h"

static const char *INDEX_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2017 Ontario Institute for Cancer Research\n";

static const char *INDEX_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " [OPTIONS] -d nanopore_raw_file_directory reads.fastq\n"
"Build an index mapping from basecalled reads to the signals measured by the sequencer\n"
"\n"
"      --help                           display this help and exit\n"
"      --version                        display version\n"
"  -v, --verbose                        display verbose output\n"
"  -d, --directory                      path to the directory containing the raw ONT signal files. This option can be given multiple times.\n"
"  -s, --sequencing-summary             the sequencing summary file from albacore, providing this option will make indexing much faster\n"
"  -f, --summary-fofn                   file containing the paths to the sequencing summary files (one per line)\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose = 0;
    static std::vector<std::string> raw_file_directories;
    static std::string reads_file;
    static std::vector<std::string> sequencing_summary_files;
    static std::string sequencing_summary_fofn;
}
static std::ostream* os_p;

//
void index_file_from_map(ReadDB& read_db, const std::string& fn, const std::multimap<std::string, std::string>& fast5_to_read_name_map)
{
    PROFILE_FUNC("index_file_from_map")

    // Check if this fast5 file is in the map
    size_t last_dir_pos = fn.find_last_of("/");
    std::string fast5_basename = last_dir_pos == std::string::npos ? fn : fn.substr(last_dir_pos + 1);

    auto range = fast5_to_read_name_map.equal_range(fast5_basename);
    for(auto iter = range.first; iter != range.second; ++iter) {
        if(read_db.has_read(iter->second)) {
            read_db.add_signal_path(iter->second.c_str(), fn);
        }
    }
}

//
void index_file_from_fast5(ReadDB& read_db, const std::string& fn)
{
    PROFILE_FUNC("index_file_from_fast5")

    fast5_file f5_file = fast5_open(fn);
    if(!fast5_is_open(f5_file)) {
        fprintf(stderr, "could not open fast5 file: %s\n", fn.c_str());
    }

    if(f5_file.is_multi_fast5) {
        std::vector<std::string> read_groups = fast5_get_multi_read_groups(f5_file);
        std::string prefix = "read_";
        for(size_t group_idx = 0; group_idx < read_groups.size(); ++group_idx) {
            std::string group_name = read_groups[group_idx];
            if(group_name.find(prefix) == 0) {
                std::string read_id = group_name.substr(prefix.size());
                read_db.add_signal_path(read_id, fn);
            }
        }
    } else {
        std::string read_id = fast5_get_read_id_single_fast5(f5_file);
        if(read_id != "") {
            read_db.add_signal_path(read_id, fn);
        }
    }
    fast5_close(f5_file);
}

//
void index_path(ReadDB& read_db, const std::string& path, const std::multimap<std::string, std::string>& fast5_to_read_name_map)
{
    fprintf(stderr, "[readdb] indexing %s\n", path.c_str());
    if (is_directory(path)) {
        auto dir_list = list_directory(path);
        for (const auto& fn : dir_list) {
            if(fn == "." or fn == "..") {
                continue;
            }

            std::string full_fn = path + "/" + fn;
            bool is_fast5 = full_fn.find(".fast5") != -1;
            bool in_map = fast5_to_read_name_map.find(fn) != fast5_to_read_name_map.end();

            // JTS 04/19: is_directory is painfully slow so we first check if the file is in the name map
            // if it is, it is definitely not a directory so we can skip the system call
            if(!in_map && is_directory(full_fn)) {
                // recurse
                index_path(read_db, full_fn, fast5_to_read_name_map);
            } else if (is_fast5) {
                if(!fast5_to_read_name_map.empty()) {
                    index_file_from_map(read_db, full_fn, fast5_to_read_name_map);
                } else {
                    index_file_from_fast5(read_db, full_fn);
                }
            }
        }
    }
}

// read sequencing summary files from the fofn and add them to the list
void process_summary_fofn()
{
    if(opt::sequencing_summary_fofn.empty()) {
        return;
    }

    // open
    std::ifstream in_file(opt::sequencing_summary_fofn.c_str());
    if(in_file.bad()) {
        fprintf(stderr, "error: could not file %s\n", opt::sequencing_summary_fofn.c_str());
        exit(EXIT_FAILURE);
    }

    // read
    std::string filename;
    while(getline(in_file, filename)) {
        opt::sequencing_summary_files.push_back(filename);
    }
}

//
void exit_bad_header(const std::string& str, const std::string& filename)
{
    fprintf(stderr, "Could not find %s column in the header of %s\n", str.c_str(), filename.c_str());
    exit(EXIT_FAILURE);
}

//
void parse_sequencing_summary(const std::string& filename, std::multimap<std::string, std::string>& out_map)
{
    // open
    std::ifstream in_file(filename.c_str());
    if(!in_file.good()) {
        fprintf(stderr, "error: could not read file %s\n", filename.c_str());
        exit(EXIT_FAILURE);
    }

    // read header to get the column index of the read and file name
    std::string header;
    getline(in_file, header);
    std::vector<std::string> fields = split(header, '\t');

    const std::string READ_NAME_STR = "read_id";
    const std::string FILENAME_STR = "filename";
    size_t filename_idx = -1;
    size_t read_name_idx = -1;

    for(size_t i = 0; i < fields.size(); ++i) {
        if(fields[i] == READ_NAME_STR) {
            read_name_idx = i;
        }

        if(fields[i] == FILENAME_STR) {
            filename_idx = i;
        }
    }

    if(filename_idx == -1) {
        exit_bad_header(FILENAME_STR, filename);
    }

    if(read_name_idx == -1) {
        exit_bad_header(READ_NAME_STR, filename);
    }

    // read records and add to map
    std::string line;
    while(getline(in_file, line)) {
        fields = split(line, '\t');
        std::string fast5_filename = fields[filename_idx];
        std::string read_name = fields[read_name_idx];
        out_map.insert(std::make_pair(fast5_filename, read_name));
    }
}

static const char* shortopts = "vd:f:s:";

enum {
    OPT_HELP = 1,
    OPT_VERSION,
    OPT_LOG_LEVEL,
};

static const struct option longopts[] = {
    { "help",                      no_argument,       NULL, OPT_HELP },
    { "version",                   no_argument,       NULL, OPT_VERSION },
    { "log-level",                 required_argument, NULL, OPT_LOG_LEVEL },
    { "verbose",                   no_argument,       NULL, 'v' },
    { "directory",                 required_argument, NULL, 'd' },
    { "sequencing-summary-file",   required_argument, NULL, 's' },
    { "summary-fofn",              required_argument, NULL, 'f' },
    { NULL, 0, NULL, 0 }
};

void parse_index_options(int argc, char** argv)
{
    bool die = false;
    std::vector< std::string> log_level;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case OPT_HELP:
                std::cout << INDEX_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << INDEX_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_LOG_LEVEL:
                log_level.push_back(arg.str());
                break;
            case 'v': opt::verbose++; break;
            case 's': opt::sequencing_summary_files.push_back(arg.str()); break;
            case 'd': opt::raw_file_directories.push_back(arg.str()); break;
            case 'f': arg >> opt::sequencing_summary_fofn; break;
        }
    }

    // set log levels
    auto default_level = (int)logger::warning + opt::verbose;
    logger::Logger::set_default_level(default_level);
    logger::Logger::set_levels_from_options(log_level, &std::clog);

    if (argc - optind < 1) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (argc - optind > 1) {
        std::cerr << SUBPROGRAM ": too many arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << INDEX_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    opt::reads_file = argv[optind++];
}

int index_main(int argc, char** argv)
{
    parse_index_options(argc, argv);

    // Read a map from fast5 files to read name from the sequencing summary files (if any)
    process_summary_fofn();
    std::multimap<std::string, std::string> fast5_to_read_name_map;
    for(const auto& ss_filename : opt::sequencing_summary_files) {
        if(opt::verbose > 2) {
            fprintf(stderr, "summary: %s\n", ss_filename.c_str());
        }
        parse_sequencing_summary(ss_filename, fast5_to_read_name_map);
    }

    // import read names, and possibly fast5 paths, from the fasta/fastq file
    ReadDB read_db;
    read_db.build(opt::reads_file);
    bool all_reads_have_paths = read_db.check_signal_paths();

    // if the input fastq did not contain a complete set of paths
    // use the fofn/directory provided to augment the index
    if(!all_reads_have_paths) {

        for(const auto& dir_name : opt::raw_file_directories) {
            index_path(read_db, dir_name, fast5_to_read_name_map);
        }
    }

    size_t num_with_path = read_db.get_num_reads_with_path();
    if(num_with_path == 0) {
        fprintf(stderr, "Error: no fast5 files found\n");
        exit(EXIT_FAILURE);
    } else {
        read_db.print_stats();
        read_db.save();
    }
    return 0;
}
<|endoftext|>


<commit_before>#ifndef MIMOSA_CHANNEL_HH
# define MIMOSA_CHANNEL_HH

# include <queue>
# include <limits>

# include "mutex.hh"
# include "condition.hh"
# include "ref-countable.hh"

namespace mimosa
{
  /**
   * @ingroup Sync
   */
  template <typename T, typename QueueType = std::queue<T> >
  class Channel : public RefCountable<Channel<T, QueueType> >,
                  private NonCopyable
  {
  public:
    inline Channel()
      : closed_(false),
        queue_(),
        mutex_(),
        cond_(),
        max_size_(std::numeric_limits<decltype (max_size_)>::max())
    {
    }

    inline void setMaxSize(size_t max_size)
    {
      Mutex::Locker locker(mutex_);
      if (max_size_ < max_size &&
          max_size_ <= queue_.size() && queue_.size() < max_size)
        push_cond_.wakeAll();
      max_size_ = max_size;
    }

    inline void maxSize() const
    {
      return max_size_;
    }

    inline bool push(const T & t)
    {
      Mutex::Locker locker(mutex_);
      do {
        if (closed_)
          return false;

        if (queue_.size() < max_size_)
          break;
        push_cond_.wait(mutex_);
      } while (true);

      queue_.push(t);
      cond_.wakeOne();
      return true;
    }

    inline bool push(T && t)
    {
      Mutex::Locker locker(mutex_);
      do {
        if (closed_)
          return false;

        if (queue_.size() < max_size_)
          break;
        push_cond_.wait(mutex_);
      } while (true);

      queue_.push(std::move(t));
      cond_.wakeOne();
      return true;
    }

    inline bool pop(T & t)
    {
      Mutex::Locker locker(mutex_);
      while (true) {
        if (!queue_.empty())
        {
          t = std::move(queue_.front());
          queue_.pop();
          push_cond_.wakeOne();
          return true;
        }
        else if (closed_)
          return false;
        cond_.wait(mutex_);
      }
      return false;
    }

    inline bool tryPop(T & t)
    {
      Mutex::Locker locker(mutex_);
      if (queue_.empty())
        return false;

      t = std::move(queue_.front());
      queue_.pop();
      push_cond_.wakeOne();
      return true;
    }

    /** closes the push end, it is possible to pop
     * until the channel is empty */
    inline void close()
    {
      Mutex::Locker locker(mutex_);
      closed_ = true;
      cond_.wakeAll();
      push_cond_.wakeAll();
    }

  private:
    inline bool empty() const
    {
      return queue_.empty();
    }

    bool      closed_;
    QueueType queue_;
    Mutex     mutex_;
    Condition cond_;
    Condition push_cond_;
    size_t    max_size_;
  };
}

#endif /* !MIMOSA_CHANNEL_HH */
<commit_msg>Channel<T>: add tryPush()<commit_after>#ifndef MIMOSA_CHANNEL_HH
# define MIMOSA_CHANNEL_HH

# include <queue>
# include <limits>

# include "mutex.hh"
# include "condition.hh"
# include "ref-countable.hh"

namespace mimosa
{
  /**
   * @ingroup Sync
   */
  template <typename T, typename QueueType = std::queue<T> >
  class Channel : public RefCountable<Channel<T, QueueType> >,
                  private NonCopyable
  {
  public:
    inline Channel()
      : closed_(false),
        queue_(),
        mutex_(),
        cond_(),
        max_size_(std::numeric_limits<decltype (max_size_)>::max())
    {
    }

    inline void setMaxSize(size_t max_size)
    {
      Mutex::Locker locker(mutex_);
      if (max_size_ < max_size &&
          max_size_ <= queue_.size() && queue_.size() < max_size)
        push_cond_.wakeAll();
      max_size_ = max_size;
    }

    inline void maxSize() const
    {
      return max_size_;
    }

    inline bool push(const T & t)
    {
      Mutex::Locker locker(mutex_);
      do {
        if (closed_)
          return false;

        if (queue_.size() < max_size_)
          break;
        push_cond_.wait(mutex_);
      } while (true);

      queue_.push(t);
      cond_.wakeOne();
      return true;
    }

    inline bool tryPush(const T & t)
    {
      Mutex::Locker locker(mutex_);
      if (closed_)
        return false;

      if (queue_.size() >= max_size_)
        return false;

      queue_.push(t);
      cond_.wakeOne();
      return true;
    }

    inline bool push(T && t)
    {
      Mutex::Locker locker(mutex_);
      do {
        if (closed_)
          return false;

        if (queue_.size() < max_size_)
          break;
        push_cond_.wait(mutex_);
      } while (true);

      queue_.push(std::move(t));
      cond_.wakeOne();
      return true;
    }

    inline bool tryPush(T && t)
    {
      Mutex::Locker locker(mutex_);
      if (closed_)
        return false;

      if (queue_.size() >= max_size_)
        return false;

      queue_.push(std::move(t));
      cond_.wakeOne();
      return true;
    }

    inline bool pop(T & t)
    {
      Mutex::Locker locker(mutex_);
      while (true) {
        if (!queue_.empty())
        {
          t = std::move(queue_.front());
          queue_.pop();
          push_cond_.wakeOne();
          return true;
        }
        else if (closed_)
          return false;
        cond_.wait(mutex_);
      }
      return false;
    }

    inline bool tryPop(T & t)
    {
      Mutex::Locker locker(mutex_);
      if (queue_.empty())
        return false;

      t = std::move(queue_.front());
      queue_.pop();
      push_cond_.wakeOne();
      return true;
    }

    /** closes the push end, it is possible to pop
     * until the channel is empty */
    inline void close()
    {
      Mutex::Locker locker(mutex_);
      closed_ = true;
      cond_.wakeAll();
      push_cond_.wakeAll();
    }

  private:
    inline bool empty() const
    {
      return queue_.empty();
    }

    bool      closed_;
    QueueType queue_;
    Mutex     mutex_;
    Condition cond_;
    Condition push_cond_;
    size_t    max_size_;
  };
}

#endif /* !MIMOSA_CHANNEL_HH */
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/fileapi/ThreadableBlobRegistry.h"

#include "core/fileapi/BlobURL.h"
#include "core/platform/network/BlobData.h"
#include "core/platform/network/BlobRegistry.h"
#include "origin/SecurityOrigin.h"
#include "origin/SecurityOriginCache.h"
#include "wtf/HashMap.h"
#include "wtf/MainThread.h"
#include "wtf/RefPtr.h"
#include "wtf/ThreadSpecific.h"
#include "wtf/text/StringHash.h"

using WTF::ThreadSpecific;

namespace WebCore {

class BlobOriginCache : public SecurityOriginCache {
public:
    BlobOriginCache();
    virtual SecurityOrigin* cachedOrigin(const KURL&) OVERRIDE;
};

struct BlobRegistryContext {
    WTF_MAKE_FAST_ALLOCATED;
public:
    BlobRegistryContext(const KURL& url, PassOwnPtr<BlobData> blobData)
        : url(url.copy())
        , blobData(blobData)
    {
        this->blobData->detachFromCurrentThread();
    }

    BlobRegistryContext(const KURL& url, const KURL& srcURL)
        : url(url.copy())
        , srcURL(srcURL.copy())
    {
    }

    BlobRegistryContext(const KURL& url)
        : url(url.copy())
    {
    }

    KURL url;
    KURL srcURL;
    OwnPtr<BlobData> blobData;
};

typedef HashMap<String, RefPtr<SecurityOrigin> > BlobURLOriginMap;
static ThreadSpecific<BlobURLOriginMap>& originMap()
{
    // We want to create the BlobOriginCache exactly once because it is shared by all the threads.
    AtomicallyInitializedStatic(BlobOriginCache*, cache = new BlobOriginCache);

    AtomicallyInitializedStatic(ThreadSpecific<BlobURLOriginMap>*, map = new ThreadSpecific<BlobURLOriginMap>);
    return *map;
}

static void registerBlobURLTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->blobData.release());
}

void ThreadableBlobRegistry::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blobData)
{
    if (isMainThread())
        blobRegistry().registerBlobURL(url, blobData);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url, blobData));
        callOnMainThread(&registerBlobURLTask, context.leakPtr());
    }
}

static void registerBlobURLFromTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
}

void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const KURL& url, const KURL& srcURL)
{
    // If the blob URL contains null origin, as in the context with unique
    // security origin or file URL, save the mapping between url and origin so
    // that the origin can be retrived when doing security origin check.
    if (origin && BlobURL::getOrigin(url) == "null")
        originMap()->add(url.string(), origin);

    if (isMainThread())
        blobRegistry().registerBlobURL(url, srcURL);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url, srcURL));
        callOnMainThread(&registerBlobURLFromTask, context.leakPtr());
    }
}

static void unregisterBlobURLTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().unregisterBlobURL(blobRegistryContext->url);
}

void ThreadableBlobRegistry::unregisterBlobURL(const KURL& url)
{
    if (BlobURL::getOrigin(url) == "null")
        originMap()->remove(url.string());

    if (isMainThread())
        blobRegistry().unregisterBlobURL(url);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url));
        callOnMainThread(&unregisterBlobURLTask, context.leakPtr());
    }
}

BlobOriginCache::BlobOriginCache()
{
    SecurityOrigin::setCache(this);
}

SecurityOrigin* BlobOriginCache::cachedOrigin(const KURL& url)
{
    return originMap()->get(url.string());
}

} // namespace WebCore
<commit_msg>Fix file-reader-sandbox-iframe.html crash<commit_after>/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/fileapi/ThreadableBlobRegistry.h"

#include "core/fileapi/BlobURL.h"
#include "core/platform/network/BlobData.h"
#include "core/platform/network/BlobRegistry.h"
#include "origin/SecurityOrigin.h"
#include "origin/SecurityOriginCache.h"
#include "wtf/HashMap.h"
#include "wtf/MainThread.h"
#include "wtf/RefPtr.h"
#include "wtf/ThreadSpecific.h"
#include "wtf/text/StringHash.h"

using WTF::ThreadSpecific;

namespace WebCore {

class BlobOriginCache : public SecurityOriginCache {
public:
    BlobOriginCache();
    virtual SecurityOrigin* cachedOrigin(const KURL&) OVERRIDE;
};

struct BlobRegistryContext {
    WTF_MAKE_FAST_ALLOCATED;
public:
    BlobRegistryContext(const KURL& url, PassOwnPtr<BlobData> blobData)
        : url(url.copy())
        , blobData(blobData)
    {
        this->blobData->detachFromCurrentThread();
    }

    BlobRegistryContext(const KURL& url, const KURL& srcURL)
        : url(url.copy())
        , srcURL(srcURL.copy())
    {
    }

    BlobRegistryContext(const KURL& url)
        : url(url.copy())
    {
    }

    KURL url;
    KURL srcURL;
    OwnPtr<BlobData> blobData;
};

typedef HashMap<String, RefPtr<SecurityOrigin> > BlobURLOriginMap;
static ThreadSpecific<BlobURLOriginMap>& originMap()
{
    // We want to create the BlobOriginCache exactly once because it is shared by all the threads.
    AtomicallyInitializedStatic(BlobOriginCache*, cache = new BlobOriginCache);

    AtomicallyInitializedStatic(ThreadSpecific<BlobURLOriginMap>*, map = new ThreadSpecific<BlobURLOriginMap>);
    return *map;
}

static void registerBlobURLTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->blobData.release());
}

void ThreadableBlobRegistry::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blobData)
{
    if (isMainThread())
        blobRegistry().registerBlobURL(url, blobData);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url, blobData));
        callOnMainThread(&registerBlobURLTask, context.leakPtr());
    }
}

static void registerBlobURLFromTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
}

void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const KURL& url, const KURL& srcURL)
{
    // If the blob URL contains null origin, as in the context with unique
    // security origin or file URL, save the mapping between url and origin so
    // that the origin can be retrived when doing security origin check.
    if (origin && BlobURL::getOrigin(url) == "null")
        originMap()->add(url.string(), origin);

    if (isMainThread())
        blobRegistry().registerBlobURL(url, srcURL);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url, srcURL));
        callOnMainThread(&registerBlobURLFromTask, context.leakPtr());
    }
}

static void unregisterBlobURLTask(void* context)
{
    OwnPtr<BlobRegistryContext> blobRegistryContext = adoptPtr(static_cast<BlobRegistryContext*>(context));
    blobRegistry().unregisterBlobURL(blobRegistryContext->url);
}

void ThreadableBlobRegistry::unregisterBlobURL(const KURL& url)
{
    if (BlobURL::getOrigin(url) == "null")
        originMap()->remove(url.string());

    if (isMainThread())
        blobRegistry().unregisterBlobURL(url);
    else {
        OwnPtr<BlobRegistryContext> context = adoptPtr(new BlobRegistryContext(url));
        callOnMainThread(&unregisterBlobURLTask, context.leakPtr());
    }
}

BlobOriginCache::BlobOriginCache()
{
    SecurityOrigin::setCache(this);
}

SecurityOrigin* BlobOriginCache::cachedOrigin(const KURL& url)
{
    if (url.protocolIs("blob"))
        return originMap()->get(url.string());
    return 0;
}

} // namespace WebCore
<|endoftext|>