<commit_before>/*************************************************************************
 *
 *  $RCSfile: swatrset.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-03 14:34:06 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include <hintids.hxx>

#ifndef _SVX_COLRITEM_HXX //autogen
#include <svx/colritem.hxx>
#endif
#ifndef _SVX_BRSHITEM_HXX //autogen
#include <svx/brshitem.hxx>
#endif
#define ITEMID_LINE             SID_ATTR_LINE_STYLE
#ifndef _SVX_BOLNITEM_HXX //autogen
#include <svx/bolnitem.hxx>
#endif
#ifndef _SVX_BOXITEM_HXX //autogen
#include <svx/boxitem.hxx>
#endif
#ifndef _XTABLE_HXX //autogen
#include <svx/xtable.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _PAGEDESC_HXX //autogen
#include <pagedesc.hxx>
#endif
#ifndef _CHARFMT_HXX
#include <charfmt.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _NODE_HXX //autogen
#include <node.hxx>
#endif
#ifndef _FORMAT_HXX //autogen
#include <format.hxx>
#endif
#ifndef _SWATRSET_HXX
#include <swatrset.hxx>
#endif
#ifndef _PARATR_HXX
#include <paratr.hxx>       // fuer SetModifyAtAttr
#endif
#ifndef _CELLATR_HXX
#include <cellatr.hxx>      // fuer SetModifyAtAttr
#endif
#ifndef _CMDID_H
#include <cmdid.h>
#endif

SwAttrPool::SwAttrPool( SwDoc* pD )
    : SfxItemPool( String::CreateFromAscii(
                                RTL_CONSTASCII_STRINGPARAM( "SWG" )),
                    POOLATTR_BEGIN, POOLATTR_END-1,
                    aSlotTab, aAttrTab ),
    pDoc( pD )
{
    SetVersionMap( 1, 1, 60, pVersionMap1 );
    SetVersionMap( 2, 1, 75, pVersionMap2 );
    SetVersionMap( 3, 1, 86, pVersionMap3 );
    SetVersionMap( 4, 1,121, pVersionMap4 );
    // OD 2004-01-21 #i18732# - apply new version map
    SetVersionMap( 5, 1,130, pVersionMap5 );
}

SwAttrSet::SwAttrSet( SwAttrPool& rPool, USHORT nWh1, USHORT nWh2 )
    : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 )
{
}

SwAttrSet::SwAttrSet( SwAttrPool& rPool, const USHORT* nWhichPairTable )
    : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 )
{
}

SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
    : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 )
{
}

int SwAttrSet::Put_BC( const SfxPoolItem& rAttr,
                    SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    int nRet = 0 != SfxItemSet::Put( rAttr );
    pOldSet = pNewSet = 0;
    return nRet;
}

int SwAttrSet::Put_BC( const SfxItemSet& rSet,
                    SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    int nRet = 0 != SfxItemSet::Put( rSet );
    pOldSet = pNewSet = 0;
    return nRet;
}

USHORT SwAttrSet::ClearItem_BC( USHORT nWhich,
                        SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    USHORT nRet = SfxItemSet::ClearItem( nWhich );
    pOldSet = pNewSet = 0;
    return nRet;
}

USHORT SwAttrSet::ClearItem_BC( USHORT nWhich1, USHORT nWhich2,
                        SwAttrSet* pOld, SwAttrSet* pNew )
{
    ASSERT( nWhich1 <= nWhich2, "kein gueltiger Bereich" );
    pNewSet = pNew;
    pOldSet = pOld;
    USHORT nRet = 0;
    for( ; nWhich1 <= nWhich2; ++nWhich1 )
        nRet += SfxItemSet::ClearItem( nWhich1 );
    pOldSet = pNewSet = 0;
    return nRet;
}

int SwAttrSet::Intersect_BC( const SfxItemSet& rSet,
                            SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    SfxItemSet::Intersect( rSet );
    pOldSet = pNewSet = 0;
    return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
}

int SwAttrSet::Differentiate_BC( const SfxItemSet& rSet,
                            SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    SfxItemSet::Differentiate( rSet );
    pOldSet = pNewSet = 0;
    return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
}

int SwAttrSet::MergeValues_BC( const SfxItemSet& rSet,
                            SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    SfxItemSet::MergeValues( rSet );
    pOldSet = pNewSet = 0;
    return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
}

    // Notification-Callback
void  SwAttrSet::Changed( const SfxPoolItem& rOld,
                                const SfxPoolItem& rNew )
{
    if( pOldSet )
        pOldSet->PutChgd( rOld );

    if( pNewSet )
        pNewSet->PutChgd( rNew );
}

// ----------------------------------------------------------------
// Sonderbehandlung fuer einige Attribute
// Setze den Modify-Pointer (alten pDefinedIn) bei folgenden Attributen:
//  - SwFmtDropCaps
//  - SwFmtPageDesc
// (Wird beim Einfuegen in Formate/Nodes gerufen)
// ----------------------------------------------------------------
void SwAttrSet::SetModifyAtAttr( const SwModify* pModify )
{
    const SfxPoolItem* pItem;
    if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, FALSE, &pItem ) &&
        ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify  )
    {
        ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_PARATR_NUMRULE, FALSE, &pItem ) &&
        ((SwNumRuleItem*)pItem)->GetDefinedIn() != pModify  )
    {
        ((SwNumRuleItem*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, FALSE, &pItem ) &&
        ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify )
    {
        // CharFormat gesetzt und dann noch in unterschiedlichen
        // Attribut Pools, dann muss das CharFormat kopiert werden!
        SwCharFmt* pCharFmt;
        if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() )
            && GetPool() != pCharFmt->GetAttrSet().GetPool() )
        {
            pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt );
            ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt );
        }
        ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, FALSE, &pItem ) &&
        ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify )
    {
        ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify );
    }
}

void SwAttrSet::CopyToModify( SwModify& rMod ) const
{
    // kopiere die Attribute ggfs. ueber Dokumentgrenzen
    SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod );
    SwFmt* pFmt = PTR_CAST( SwFmt, &rMod );

    if( pCNd || pFmt )
    {
        if( Count() )
        {
            const SfxPoolItem* pItem;
            const SwDoc *pSrcDoc = GetDoc();
            SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc();

            // muss die NumRule kopiert werden?
            if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
                                    RES_PARATR_NUMRULE, FALSE, &pItem ) )
            {
                const String& rNm = ((SwNumRuleItem*)pItem)->GetValue();
                if( rNm.Len() )
                {
                    SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm );
                    if( pDestRule )
                        pDestRule->SetInvalidRule( TRUE );
                    else
                        pDstDoc->MakeNumRule( rNm,
                                            pSrcDoc->FindNumRulePtr( rNm ) );
                }
            }

            // JP 04.02.99: Task #61467# Seitenvorlagenwechsel mit kopieren
            //              Gegenueber dem alten Verhalten, sie zu entfernen
            const SwPageDesc* pPgDesc;
            if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
                                            RES_PAGEDESC, FALSE, &pItem ) &&
                0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) )
            {
                SfxItemSet aTmpSet( *this );

                // JP 09.02.99: und jetzt doch wieder nur entfernen
                aTmpSet.ClearItem( RES_PAGEDESC );

/*************************************************************************
                SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName(
                                                    pPgDesc->GetName() );
                if( !pDstPgDesc )
                {
                    // dann kopieren, ansonsten den benutzen
                    pDstPgDesc = &pDstDoc->_GetPageDesc( pDstDoc->MakePageDesc(
                                                    pPgDesc->GetName() ));
                    pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc );
                }
                SwFmtPageDesc aDesc( pDstPgDesc );
                aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() );
                aTmpSet.Put( aDesc );
************************************************************************/

                if( pCNd )
                    pCNd->SetAttr( aTmpSet );
                else
                    pFmt->SetAttr( aTmpSet );
            }
            else if( pCNd )
                pCNd->SetAttr( *this );
            else
                pFmt->SetAttr( *this );
        }
    }
#ifndef PRODUCT
    else
        ASSERT( !this, "weder Format noch ContentNode - keine Attribute kopiert");
#endif
}

// check if ID is InRange of AttrSet-Ids
BOOL IsInRange( const USHORT* pRange, const USHORT nId )
{
    while( *pRange )
    {
        if( *pRange <= nId && nId <= *(pRange+1) )
            return TRUE;
        pRange += 2;
    }
    return FALSE;
}

<commit_msg>INTEGRATION: CWS tune05 (1.5.210); FILE MERGED 2004/07/22 11:08:24 cmc 1.5.210.1: #i30554# unused methods<commit_after>/*************************************************************************
 *
 *  $RCSfile: swatrset.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2004-08-12 12:11:59 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include <hintids.hxx>

#ifndef _SVX_COLRITEM_HXX //autogen
#include <svx/colritem.hxx>
#endif
#ifndef _SVX_BRSHITEM_HXX //autogen
#include <svx/brshitem.hxx>
#endif
#define ITEMID_LINE             SID_ATTR_LINE_STYLE
#ifndef _SVX_BOLNITEM_HXX //autogen
#include <svx/bolnitem.hxx>
#endif
#ifndef _SVX_BOXITEM_HXX //autogen
#include <svx/boxitem.hxx>
#endif
#ifndef _XTABLE_HXX //autogen
#include <svx/xtable.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _PAGEDESC_HXX //autogen
#include <pagedesc.hxx>
#endif
#ifndef _CHARFMT_HXX
#include <charfmt.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _NODE_HXX //autogen
#include <node.hxx>
#endif
#ifndef _FORMAT_HXX //autogen
#include <format.hxx>
#endif
#ifndef _SWATRSET_HXX
#include <swatrset.hxx>
#endif
#ifndef _PARATR_HXX
#include <paratr.hxx>       // fuer SetModifyAtAttr
#endif
#ifndef _CELLATR_HXX
#include <cellatr.hxx>      // fuer SetModifyAtAttr
#endif
#ifndef _CMDID_H
#include <cmdid.h>
#endif

SwAttrPool::SwAttrPool( SwDoc* pD )
    : SfxItemPool( String::CreateFromAscii(
                                RTL_CONSTASCII_STRINGPARAM( "SWG" )),
                    POOLATTR_BEGIN, POOLATTR_END-1,
                    aSlotTab, aAttrTab ),
    pDoc( pD )
{
    SetVersionMap( 1, 1, 60, pVersionMap1 );
    SetVersionMap( 2, 1, 75, pVersionMap2 );
    SetVersionMap( 3, 1, 86, pVersionMap3 );
    SetVersionMap( 4, 1,121, pVersionMap4 );
    // OD 2004-01-21 #i18732# - apply new version map
    SetVersionMap( 5, 1,130, pVersionMap5 );
}

SwAttrSet::SwAttrSet( SwAttrPool& rPool, USHORT nWh1, USHORT nWh2 )
    : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 )
{
}

SwAttrSet::SwAttrSet( SwAttrPool& rPool, const USHORT* nWhichPairTable )
    : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 )
{
}

SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
    : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 )
{
}

int SwAttrSet::Put_BC( const SfxPoolItem& rAttr,
                    SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    int nRet = 0 != SfxItemSet::Put( rAttr );
    pOldSet = pNewSet = 0;
    return nRet;
}

int SwAttrSet::Put_BC( const SfxItemSet& rSet,
                    SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    int nRet = 0 != SfxItemSet::Put( rSet );
    pOldSet = pNewSet = 0;
    return nRet;
}

USHORT SwAttrSet::ClearItem_BC( USHORT nWhich,
                        SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    USHORT nRet = SfxItemSet::ClearItem( nWhich );
    pOldSet = pNewSet = 0;
    return nRet;
}

USHORT SwAttrSet::ClearItem_BC( USHORT nWhich1, USHORT nWhich2,
                        SwAttrSet* pOld, SwAttrSet* pNew )
{
    ASSERT( nWhich1 <= nWhich2, "kein gueltiger Bereich" );
    pNewSet = pNew;
    pOldSet = pOld;
    USHORT nRet = 0;
    for( ; nWhich1 <= nWhich2; ++nWhich1 )
        nRet += SfxItemSet::ClearItem( nWhich1 );
    pOldSet = pNewSet = 0;
    return nRet;
}

int SwAttrSet::Intersect_BC( const SfxItemSet& rSet,
                            SwAttrSet* pOld, SwAttrSet* pNew )
{
    pNewSet = pNew;
    pOldSet = pOld;
    SfxItemSet::Intersect( rSet );
    pOldSet = pNewSet = 0;
    return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
}

// Notification-Callback
void  SwAttrSet::Changed( const SfxPoolItem& rOld,
                                const SfxPoolItem& rNew )
{
    if( pOldSet )
        pOldSet->PutChgd( rOld );

    if( pNewSet )
        pNewSet->PutChgd( rNew );
}

// ----------------------------------------------------------------
// Sonderbehandlung fuer einige Attribute
// Setze den Modify-Pointer (alten pDefinedIn) bei folgenden Attributen:
//  - SwFmtDropCaps
//  - SwFmtPageDesc
// (Wird beim Einfuegen in Formate/Nodes gerufen)
// ----------------------------------------------------------------
void SwAttrSet::SetModifyAtAttr( const SwModify* pModify )
{
    const SfxPoolItem* pItem;
    if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, FALSE, &pItem ) &&
        ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify  )
    {
        ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_PARATR_NUMRULE, FALSE, &pItem ) &&
        ((SwNumRuleItem*)pItem)->GetDefinedIn() != pModify  )
    {
        ((SwNumRuleItem*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, FALSE, &pItem ) &&
        ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify )
    {
        // CharFormat gesetzt und dann noch in unterschiedlichen
        // Attribut Pools, dann muss das CharFormat kopiert werden!
        SwCharFmt* pCharFmt;
        if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() )
            && GetPool() != pCharFmt->GetAttrSet().GetPool() )
        {
            pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt );
            ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt );
        }
        ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify );
    }

    if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, FALSE, &pItem ) &&
        ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify )
    {
        ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify );
    }
}

void SwAttrSet::CopyToModify( SwModify& rMod ) const
{
    // kopiere die Attribute ggfs. ueber Dokumentgrenzen
    SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod );
    SwFmt* pFmt = PTR_CAST( SwFmt, &rMod );

    if( pCNd || pFmt )
    {
        if( Count() )
        {
            const SfxPoolItem* pItem;
            const SwDoc *pSrcDoc = GetDoc();
            SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc();

            // muss die NumRule kopiert werden?
            if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
                                    RES_PARATR_NUMRULE, FALSE, &pItem ) )
            {
                const String& rNm = ((SwNumRuleItem*)pItem)->GetValue();
                if( rNm.Len() )
                {
                    SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm );
                    if( pDestRule )
                        pDestRule->SetInvalidRule( TRUE );
                    else
                        pDstDoc->MakeNumRule( rNm,
                                            pSrcDoc->FindNumRulePtr( rNm ) );
                }
            }

            // JP 04.02.99: Task #61467# Seitenvorlagenwechsel mit kopieren
            //              Gegenueber dem alten Verhalten, sie zu entfernen
            const SwPageDesc* pPgDesc;
            if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
                                            RES_PAGEDESC, FALSE, &pItem ) &&
                0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) )
            {
                SfxItemSet aTmpSet( *this );

                // JP 09.02.99: und jetzt doch wieder nur entfernen
                aTmpSet.ClearItem( RES_PAGEDESC );

/*************************************************************************
                SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName(
                                                    pPgDesc->GetName() );
                if( !pDstPgDesc )
                {
                    // dann kopieren, ansonsten den benutzen
                    pDstPgDesc = &pDstDoc->_GetPageDesc( pDstDoc->MakePageDesc(
                                                    pPgDesc->GetName() ));
                    pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc );
                }
                SwFmtPageDesc aDesc( pDstPgDesc );
                aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() );
                aTmpSet.Put( aDesc );
************************************************************************/

                if( pCNd )
                    pCNd->SetAttr( aTmpSet );
                else
                    pFmt->SetAttr( aTmpSet );
            }
            else if( pCNd )
                pCNd->SetAttr( *this );
            else
                pFmt->SetAttr( *this );
        }
    }
#ifndef PRODUCT
    else
        ASSERT( !this, "weder Format noch ContentNode - keine Attribute kopiert");
#endif
}

// check if ID is InRange of AttrSet-Ids
BOOL IsInRange( const USHORT* pRange, const USHORT nId )
{
    while( *pRange )
    {
        if( *pRange <= nId && nId <= *(pRange+1) )
            return TRUE;
        pRange += 2;
    }
    return FALSE;
}

<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS swdrawpositioning (1.114.6); FILE MERGED 2004/05/04 06:25:06 od 1.114.6.3: RESYNC: (1.114-1.115); FILE MERGED 2004/04/21 15:25:10 mmaher 1.114.6.2: #i26790# First stab at using the new anchoring option for drawing objects 2004/04/07 10:43:15 od 1.114.6.1: #i26791# - adjustments for the unification of the positioning of 	   Writer fly frames and drawing objects<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS os8 (1.3.138); FILE MERGED 2003/04/03 07:15:07 os 1.3.138.1: #108583# precompiled headers removed<commit_after><|endoftext|>


<commit_before>#include "dynet/nodes-conv.h"

#include <sstream>
#include <limits>
#include <cmath>
#include <stdexcept>
#include <array>

#include "dynet/functors.h"
#include "dynet/nodes-macros.h"
#include "third_party/eigen_pooling.h"

#if HAVE_CUDA
#include "dynet/cuda.h"
#include "dynet/gpu-ops.h"
#endif

using namespace std;

namespace dynet {

#ifndef __CUDACC__

string MaxPooling2D::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "maxpooling2d(" << arg_names[0] << ")";
  return s.str();
}

Dim MaxPooling2D::dim_forward(const vector<Dim>& xs) const {
  if (xs.size() != 1) {
    ostringstream s; s << "MaxPooling2D requires exactly one input: " << xs;
    throw std::invalid_argument(s.str());
  }
  if (xs[0].ndims() != 3) {
    ostringstream s; s << "Bad input dimensions in MaxPooling2D: " << xs;
    throw std::invalid_argument(s.str());
  }
  if (is_valid && (xs[0].d[0] < ksize[0] || xs[0].d[1] < ksize[1])) {
    ostringstream s; s << "Bad input dimensions in MaxPooling2D: \
        in VALID mode, the kernel size cannot be greater than the feature map size" << xs;
    throw std::invalid_argument(s.str());
  }
  unsigned bs = xs[0].batch_elems();
  std::vector<long> output_shape(3);
  output_shape[2] = static_cast<long>(xs[0].d[2]);
  for (unsigned i = 0; i < 2; ++i) {
    float input_dim = static_cast<float>(xs[0].d[i]);
    float kernel_dim = static_cast<float>(ksize[i]);
    float s = static_cast<float>(stride[i]);
    if (is_valid) {
      output_shape[i] = static_cast<long>(ceil((input_dim - kernel_dim + 1) / s));
    } else {
      output_shape[i] = static_cast<long>(ceil(input_dim / s));
    }
  }
  return Dim(output_shape, bs);
}

size_t MaxPooling2D::aux_storage_size() const {
  vector<unsigned> input_size(arity());
  for (unsigned i = 0; i < arity(); ++i) {
    input_size[i] = get_cg()->nodes[args[i]]->dim.size();
  }
  size_t nbytes = 0;
#if HAVE_CUDNN
  nbytes += 0;
#else
  nbytes += sizeof(float) * (2 * input_size[0] + 2 * input_size[1] + dim.size());
#endif
  return nbytes;
}
#endif

template<class MyDevice>
void MaxPooling2D::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 1, "Failed dimension check in MaxPooling2D::forward, exactly one input");
  DYNET_ASSERT(fx.d.bd == xs[0]->d.bd, "Failed dimension check in MaxPooling2D::forward, batchsize not match");
  DYNET_ASSERT(fx.d[2] == xs[0]->d[2], "Failed dimension check in MaxPooling2D::forward, #channel not match");
#ifdef __CUDACC__
#if HAVE_CUDNN
  if (cudnn_maxpool_op_ == NULL) {
    cudnn_maxpool_op_ = new CudnnMaxPooling2DOp(ksize, stride, is_valid);
  }
  cudnn_maxpool_op_->forward_impl(dev, xs, fx);
#else
  throw std::runtime_error("MaxPooling2D::forward_dev_impl not supported without CUDNN");
#endif
#else
  NodeMemPool aux_mem_pool = NodeMemPool(aux_storage_size(), aux_mem);
  Eigen::PaddingType padding_type = is_valid ? Eigen::PADDING_VALID : Eigen::PADDING_SAME;
  // convert x from HWCN to CHWN
  void* CHWN_x_mem = aux_mem_pool.allocate(xs[0]->d.size() * sizeof(float));
  Tensor CHWN_x = Tensor(Dim({xs[0]->d[2], xs[0]->d[0], xs[0]->d[1]}, xs[0]->d.bd), static_cast<float*>(CHWN_x_mem), xs[0]->device, DeviceMempool::FXS);
  Eigen::array<ptrdiff_t, 4> shuffles;
  shuffles[0] = 2; shuffles[1] = 0; shuffles[2] = 1; shuffles[3] = 3;
  CHWN_x.tb<3>().device(*dev.edevice) = xs[0]->tb<3>().shuffle(shuffles);
  // allocate temp memory and compute
  void* CHWN_y_mem = aux_mem_pool.allocate(fx.d.size() * sizeof(float));
  Tensor CHWN_y = Tensor(Dim({fx.d[2], fx.d[0], fx.d[1]}, fx.d.bd), static_cast<float*>(CHWN_y_mem), fx.device, DeviceMempool::FXS);
  CHWN_y.tb<3>().device(*dev.edevice) = Eigen::SpatialMaxPooling(CHWN_x.tb<3>(), ksize[0], ksize[1], stride[0], stride[1], padding_type);
  // convert y from CHWN to HWCN
  shuffles[0] = 1; shuffles[1] = 2; shuffles[2] = 0; shuffles[3] = 3;
  fx.tb<3>().device(*dev.edevice) = CHWN_y.tb<3>().shuffle(shuffles);
#endif
}

template<class MyDevice>
void MaxPooling2D::backward_dev_impl(const MyDevice & dev,
                         const vector<const Tensor*>& xs,
                         const Tensor& fx,
                         const Tensor& dEdf,
                         unsigned i,
                         Tensor& dEdxi) const {
  DYNET_ASSERT(dEdf.d == fx.d, "Failed dimension check in MaxPooling2D::backward");
  DYNET_ASSERT(dEdxi.d == xs[i]->d, "Failed dimension check in MaxPooling2D::backward");
  DYNET_ASSERT(i == 0, "Failed dimension check in MaxPooling2D::backward: i must be 0");
#ifdef __CUDACC__
#if HAVE_CUDNN
  DYNET_ASSERT(cudnn_maxpool_op_ != NULL, "cudnn maxpool operator is not initialized");
  cudnn_maxpool_op_->backward_impl(dev, xs, fx, dEdf, i, dEdxi);
#else
  throw std::runtime_error("MaxPooling2D::backward_dev_impl not supported without CUDNN");
#endif
#else
  int pad_along_height = ((fx.d[0] - 1) * stride[0] +
                  ksize[0] - xs[0]->d[0]);
  int pad_along_width = ((fx.d[1] - 1) * stride[1] +
                 ksize[1] - xs[0]->d[1]);
  int pad_top = is_valid ? 0 : pad_along_height / 2;
  int pad_left = is_valid ? 0 : pad_along_width / 2;
  for (int b = 0; b < fx.d.bd; ++b) {
    for (int i = 0; i < fx.d[0]; ++i) {
      for (int j = 0; j < fx.d[1]; ++j) {
        for (int ch = 0; ch < fx.d[2]; ++ch) {
          int max_r = 0, max_c = 0;
          float max_val;
          bool is_feasible = false;
          for (int r = 0; r < ksize[0]; ++r) {
            for (int c = 0; c < ksize[1]; ++c) {
              int row = stride[0] * i + r - pad_top;
              int col = stride[1] * j + c - pad_left;
              if (((col < xs[0]->d[1]) && (row < xs[0]->d[0])) && ((0 <= col) && (0 <= row))) {
                if (!is_feasible) {
                  max_val = xs[0]->tb<3>()(row, col, ch, b);
                  max_r = row; max_c = col; is_feasible = true;
		        } else if (xs[0]->tb<3>()(row, col, ch, b) > max_val) {
                  max_val = xs[0]->tb<3>()(row, col, ch, b);
                  max_r = row; max_c = col;
                }
              }
            }
          }
          (dEdxi.tb<3>())(max_r, max_c, ch, b) += (dEdf.tb<3>())(i, j, ch, b);
        }
      }
    }
  }
#endif
}
DYNET_NODE_INST_DEV_IMPL(MaxPooling2D)

} // namespace dynet
<commit_msg>Fixed maxpooling out of bounds exception<commit_after>#include "dynet/nodes-conv.h"

#include <sstream>
#include <limits>
#include <cmath>
#include <stdexcept>
#include <array>

#include "dynet/functors.h"
#include "dynet/nodes-macros.h"
#include "third_party/eigen_pooling.h"

#if HAVE_CUDA
#include "dynet/cuda.h"
#include "dynet/gpu-ops.h"
#endif

using namespace std;

namespace dynet {

#ifndef __CUDACC__

string MaxPooling2D::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "maxpooling2d(" << arg_names[0] << ")";
  return s.str();
}

Dim MaxPooling2D::dim_forward(const vector<Dim>& xs) const {
  if (xs.size() != 1) {
    ostringstream s; s << "MaxPooling2D requires exactly one input: " << xs;
    throw std::invalid_argument(s.str());
  }
  if (xs[0].ndims() != 3) {
    ostringstream s; s << "Bad input dimensions in MaxPooling2D: " << xs;
    throw std::invalid_argument(s.str());
  }
  if (is_valid && (xs[0].d[0] < ksize[0] || xs[0].d[1] < ksize[1])) {
    ostringstream s; s << "Bad input dimensions in MaxPooling2D: \
        in VALID mode, the kernel size cannot be greater than the feature map size" << xs;
    throw std::invalid_argument(s.str());
  }
  unsigned bs = xs[0].batch_elems();
  std::vector<long> output_shape(3);
  output_shape[2] = static_cast<long>(xs[0].d[2]);
  for (unsigned i = 0; i < 2; ++i) {
    float input_dim = static_cast<float>(xs[0].d[i]);
    float kernel_dim = static_cast<float>(ksize[i]);
    float s = static_cast<float>(stride[i]);
    if (is_valid) {
      output_shape[i] = static_cast<long>(ceil((input_dim - kernel_dim + 1) / s));
    } else {
      output_shape[i] = static_cast<long>(ceil(input_dim / s));
    }
  }
  return Dim(output_shape, bs);
}

size_t MaxPooling2D::aux_storage_size() const {
  return sizeof(float) * (2 * get_cg()->nodes[args[0]]->dim.size() + dim.size());
}
#endif

template<class MyDevice>
void MaxPooling2D::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 1, "Failed dimension check in MaxPooling2D::forward, exactly one input");
  DYNET_ASSERT(fx.d.bd == xs[0]->d.bd, "Failed dimension check in MaxPooling2D::forward, batchsize not match");
  DYNET_ASSERT(fx.d[2] == xs[0]->d[2], "Failed dimension check in MaxPooling2D::forward, #channel not match");
#ifdef __CUDACC__
#if HAVE_CUDNN
  if (cudnn_maxpool_op_ == NULL) {
    cudnn_maxpool_op_ = new CudnnMaxPooling2DOp(ksize, stride, is_valid);
  }
  cudnn_maxpool_op_->forward_impl(dev, xs, fx);
#else
  throw std::runtime_error("MaxPooling2D::forward_dev_impl not supported without CUDNN");
#endif
#else
  NodeMemPool aux_mem_pool = NodeMemPool(aux_storage_size(), aux_mem);
  Eigen::PaddingType padding_type = is_valid ? Eigen::PADDING_VALID : Eigen::PADDING_SAME;
  // convert x from HWCN to CHWN
  void* CHWN_x_mem = aux_mem_pool.allocate(xs[0]->d.size() * sizeof(float));
  Tensor CHWN_x = Tensor(Dim({xs[0]->d[2], xs[0]->d[0], xs[0]->d[1]}, xs[0]->d.bd), static_cast<float*>(CHWN_x_mem), xs[0]->device, DeviceMempool::FXS);
  Eigen::array<ptrdiff_t, 4> shuffles;
  shuffles[0] = 2; shuffles[1] = 0; shuffles[2] = 1; shuffles[3] = 3;
  CHWN_x.tb<3>().device(*dev.edevice) = xs[0]->tb<3>().shuffle(shuffles);
  // allocate temp memory and compute
  void* CHWN_y_mem = aux_mem_pool.allocate(fx.d.size() * sizeof(float));
  Tensor CHWN_y = Tensor(Dim({fx.d[2], fx.d[0], fx.d[1]}, fx.d.bd), static_cast<float*>(CHWN_y_mem), fx.device, DeviceMempool::FXS);
  CHWN_y.tb<3>().device(*dev.edevice) = Eigen::SpatialMaxPooling(CHWN_x.tb<3>(), ksize[0], ksize[1], stride[0], stride[1], padding_type);
  // convert y from CHWN to HWCN
  shuffles[0] = 1; shuffles[1] = 2; shuffles[2] = 0; shuffles[3] = 3;
  fx.tb<3>().device(*dev.edevice) = CHWN_y.tb<3>().shuffle(shuffles);
#endif
}

template<class MyDevice>
void MaxPooling2D::backward_dev_impl(const MyDevice & dev,
                         const vector<const Tensor*>& xs,
                         const Tensor& fx,
                         const Tensor& dEdf,
                         unsigned i,
                         Tensor& dEdxi) const {
  DYNET_ASSERT(dEdf.d == fx.d, "Failed dimension check in MaxPooling2D::backward");
  DYNET_ASSERT(dEdxi.d == xs[i]->d, "Failed dimension check in MaxPooling2D::backward");
  DYNET_ASSERT(i == 0, "Failed dimension check in MaxPooling2D::backward: i must be 0");
#ifdef __CUDACC__
#if HAVE_CUDNN
  DYNET_ASSERT(cudnn_maxpool_op_ != NULL, "cudnn maxpool operator is not initialized");
  cudnn_maxpool_op_->backward_impl(dev, xs, fx, dEdf, i, dEdxi);
#else
  throw std::runtime_error("MaxPooling2D::backward_dev_impl not supported without CUDNN");
#endif
#else
  int pad_along_height = ((fx.d[0] - 1) * stride[0] +
                  ksize[0] - xs[0]->d[0]);
  int pad_along_width = ((fx.d[1] - 1) * stride[1] +
                 ksize[1] - xs[0]->d[1]);
  int pad_top = is_valid ? 0 : pad_along_height / 2;
  int pad_left = is_valid ? 0 : pad_along_width / 2;
  for (int b = 0; b < fx.d.bd; ++b) {
    for (int i = 0; i < fx.d[0]; ++i) {
      for (int j = 0; j < fx.d[1]; ++j) {
        for (int ch = 0; ch < fx.d[2]; ++ch) {
          int max_r = 0, max_c = 0;
          float max_val;
          bool is_feasible = false;
          for (int r = 0; r < ksize[0]; ++r) {
            for (int c = 0; c < ksize[1]; ++c) {
              int row = stride[0] * i + r - pad_top;
              int col = stride[1] * j + c - pad_left;
              if (((col < xs[0]->d[1]) && (row < xs[0]->d[0])) && ((0 <= col) && (0 <= row))) {
                if (!is_feasible) {
                  max_val = xs[0]->tb<3>()(row, col, ch, b);
                  max_r = row; max_c = col; is_feasible = true;
		        } else if (xs[0]->tb<3>()(row, col, ch, b) > max_val) {
                  max_val = xs[0]->tb<3>()(row, col, ch, b);
                  max_r = row; max_c = col;
                }
              }
            }
          }
          (dEdxi.tb<3>())(max_r, max_c, ch, b) += (dEdf.tb<3>())(i, j, ch, b);
        }
      }
    }
  }
#endif
}
DYNET_NODE_INST_DEV_IMPL(MaxPooling2D)

} // namespace dynet
<|endoftext|>


<commit_before>//  (C) Copyright Gennadiy Rozental 2002-2003.
//  Permission to copy, use, modify, sell and distribute this software
//  is granted provided this copyright notice appears in all copies.
//  This software is provided "as is" without express or implied warranty,
//  and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : tests parameterized tests
// ***************************************************************************

// Boost.Test
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/unit_test_result.hpp>
#include <boost/test/test_tools.hpp>
#if !defined ( __GNUC__ ) || __GNUC__ > 2
#include <boost/test/detail/nullstream.hpp>
typedef boost::onullstream onullstream_type;
#else
typedef boost::test_toolbox::output_test_stream onullstream_type;
#endif

namespace utf=boost::unit_test_framework;

#include <list>
#include <iostream>
#include <boost/scoped_ptr.hpp>

//____________________________________________________________________________//

void test0( int i )
{
    BOOST_CHECK( i%2 == 0 );
}

//____________________________________________________________________________//

void test1( int i )
{
    BOOST_CHECK( i%2 == 0 );
    if( i%3 == 0 ) {
        throw 124;
    }
}

//____________________________________________________________________________//

#if defined(__BORLANDC__) && (__BORLANDC__ < 0x570)
#define BOOST_PARAM_TEST_CASE__( arg1, arg2, arg3 ) \
    boost::unit_test_framework::create_test_case<int*,int>( (arg1), std::string( "" ), (arg2), (arg3) )
#else
#define BOOST_PARAM_TEST_CASE__( arg1, arg2, arg3 ) BOOST_PARAM_TEST_CASE( arg1, arg2, arg3 )
#endif

int test_main( int, char* [] ) {
    utf::unit_test_counter              num_of_failures;
    bool                                exception_caught;
    bool                                passed;
    onullstream_type                    null_output;
    boost::scoped_ptr<utf::test_case>   test;

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 2, 2, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK( num_of_failures == 0 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 2, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK( num_of_failures == 1 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 1, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 1, 1 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)3 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 6, 6, 6 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    passed = utf::unit_test_result::instance().has_passed();
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)0 );
    BOOST_CHECK( !exception_caught );
    BOOST_CHECK( !passed );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 0, 3, 9 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 2, 3, 9 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 3, 2, 6 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (size_t)1 );
    BOOST_CHECK( !exception_caught );

    return 0;
}

//____________________________________________________________________________//

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.7  2003/06/11 15:47:03  rogeeff
//  eliminate mismatch types warning
//
//  Revision 1.6  2003/06/10 07:57:33  rogeeff
//  test_case_template_test added
//  parameterized test updated
//
//  Revision 1.5  2003/06/09 09:25:24  rogeeff
//  1.30.beta1
//
//  Revision 1.4  2003/02/15 21:52:37  rogeeff
//  mingw ostream fix
//
//  Revision 1.3  2002/12/09 05:16:10  rogeeff
//  switched to use utf::unit_test_result_saver for internal testing
//
//  Revision 1.2  2002/11/02 20:04:43  rogeeff
//  release 1.29.0 merged into the main trank
//

// ***************************************************************************

// EOF
<commit_msg>*** empty log message ***<commit_after>//  (C) Copyright Gennadiy Rozental 2002-2003.
//  Permission to copy, use, modify, sell and distribute this software
//  is granted provided this copyright notice appears in all copies.
//  This software is provided "as is" without express or implied warranty,
//  and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : tests parameterized tests
// ***************************************************************************

// Boost.Test
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/unit_test_result.hpp>
#include <boost/test/test_tools.hpp>
#if !defined ( __GNUC__ ) || __GNUC__ > 2
#include <boost/test/detail/nullstream.hpp>
typedef boost::onullstream onullstream_type;
#else
typedef boost::test_toolbox::output_test_stream onullstream_type;
#endif

namespace utf=boost::unit_test_framework;

#include <list>
#include <iostream>
#include <boost/scoped_ptr.hpp>

//____________________________________________________________________________//

void test0( int i )
{
    BOOST_CHECK( i%2 == 0 );
}

//____________________________________________________________________________//

void test1( int i )
{
    BOOST_CHECK( i%2 == 0 );
    if( i%3 == 0 ) {
        throw 124;
    }
}

//____________________________________________________________________________//

#if defined(__BORLANDC__) && (__BORLANDC__ < 0x570)
#define BOOST_PARAM_TEST_CASE__( arg1, arg2, arg3 ) \
    boost::unit_test_framework::create_test_case<int*,int>( (arg1), std::string( "" ), (arg2), (arg3) )
#else
#define BOOST_PARAM_TEST_CASE__( arg1, arg2, arg3 ) BOOST_PARAM_TEST_CASE( arg1, arg2, arg3 )
#endif

int test_main( int, char* [] ) {
    utf::unit_test_counter              num_of_failures;
    bool                                exception_caught;
    bool                                passed;
    onullstream_type                    null_output;
    boost::scoped_ptr<utf::test_case>   test;

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 2, 2, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK( num_of_failures == 0 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 2, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK( num_of_failures == 1 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 1, 2 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 1, 1, 1 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)3 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 6, 6, 6 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    passed = utf::unit_test_result::instance().has_passed();
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)0 );
    BOOST_CHECK( !exception_caught );
    BOOST_CHECK( !passed );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 0, 3, 9 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 2, 3, 9 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)2 );
    BOOST_CHECK( !exception_caught );

    utf::unit_test_log::instance().set_log_stream( null_output );
    {
    utf::unit_test_result_saver saver;
    int test_data[] = { 3, 2, 6 };
    test.reset( BOOST_PARAM_TEST_CASE__( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) );

    test->run();

    utf::unit_test_result::instance().failures_details( num_of_failures, exception_caught );
    }

    utf::unit_test_log::instance().set_log_stream( std::cout );
    BOOST_CHECK_EQUAL( num_of_failures, (std::size_t)1 );
    BOOST_CHECK( !exception_caught );

    return 0;
}

//____________________________________________________________________________//

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.8  2003/06/12 00:02:39  rogeeff
//  *** empty log message ***
//
//  Revision 1.7  2003/06/11 15:47:03  rogeeff
//  eliminate mismatch types warning
//
//  Revision 1.6  2003/06/10 07:57:33  rogeeff
//  test_case_template_test added
//  parameterized test updated
//
//  Revision 1.5  2003/06/09 09:25:24  rogeeff
//  1.30.beta1
//
//  Revision 1.4  2003/02/15 21:52:37  rogeeff
//  mingw ostream fix
//
//  Revision 1.3  2002/12/09 05:16:10  rogeeff
//  switched to use utf::unit_test_result_saver for internal testing
//
//  Revision 1.2  2002/11/02 20:04:43  rogeeff
//  release 1.29.0 merged into the main trank
//

// ***************************************************************************

// EOF
<|endoftext|>


<commit_before>#include "SimplifySpecializations.h"
#include "IROperator.h"
#include "IRMutator.h"
#include "Simplify.h"
#include "Substitute.h"
#include "Definition.h"
#include "IREquality.h"

#include <set>

namespace Halide{
namespace Internal {

using std::map;
using std::set;
using std::string;
using std::vector;

namespace {

void substitute_value_in_var(const string &var, Expr value, vector<Definition> &definitions) {
    for (Definition &def : definitions) {
        for (auto &def_arg : def.args()) {
            def_arg = simplify(substitute(var, value, def_arg));
        }
        for (auto &def_val : def.values()) {
            def_val = simplify(substitute(var, value, def_val));
        }
    }
}

class SimplifyUsingFact : public IRMutator {
public:
    using IRMutator::mutate;

    Expr mutate(Expr e) {
        if (e.type().is_bool()) {
            if (equal(fact, e) ||
                can_prove(!fact || e)) {
                // fact implies e
                return const_true();
            }
            if (equal(fact, !e) ||
                equal(!fact, e) ||
                can_prove(!fact || !e)) {
                // fact implies !e
                return const_false();
            }
        }
        return IRMutator::mutate(e);
    }

    Expr fact;
    SimplifyUsingFact(Expr f) : fact(f) {}
};

void simplify_using_fact(Expr fact, vector<Definition> &definitions) {
    for (Definition &def : definitions) {
        for (auto &def_arg : def.args()) {
            def_arg = simplify(SimplifyUsingFact(fact).mutate(def_arg));
        }
        for (auto &def_val : def.values()) {
            def_val = simplify(SimplifyUsingFact(fact).mutate(def_val));
        }
    }
}

bool equal(const std::vector<Expr> &a, const std::vector<Expr> &b) {
    if (a.size() != b.size()) return false;
    for (size_t i = 0; i < a.size(); ++i) {
        if (!equal(a[i], b[i])) return false;
    }
    return true;
}

vector<Definition> propagate_specialization_in_definition(Definition &def, const string &name) {
    vector<Definition> result;

    result.push_back(def);

    vector<Specialization> &specializations = def.specializations();

    // Prune specializations based on constants:
    // -- Any Specializations that have const-false as a condition
    // can never trigger; go ahead and prune them now to save time & energy
    // during later phases.
    // -- Once we encounter a Specialization that is const-true, no subsequent
    // Specializations can ever trigger (since we evaluate them in order),
    // so erase them.
    bool seen_const_true = false;
    for (auto it = specializations.begin(); it != specializations.end(); /*no-increment*/) {
        Expr old_c = it->condition;
        Expr c = simplify(it->condition);
        // Go ahead and save the simplified condition now
        it->condition = c;
        if (is_zero(c) || seen_const_true) {
            debug(1) << "Erasing unreachable specialization ("
                << old_c << ") -> (" << c << ") for function \"" << name << "\"\n";
            it = specializations.erase(it);
        } else {
            it++;
        }
        seen_const_true |= is_one(c);
    }

    // If the final Specialization is const-true, then the default schedule
    // for the definition will never be run: replace the definition's main
    // schedule with the one from the final Specialization and prune it from
    // the list. This may leave the list of Specializations empty.
    if (!specializations.empty() && is_one(specializations.back().condition)) {
        debug(1) << "Replacing default Schedule with const-true specialization for function \"" << name << "\"\n";
        const Definition s_def = specializations.back().definition;
        specializations.pop_back();

        def.predicate() = s_def.predicate();
        // values and args should be identical -- if not, something is badly wrong.
        internal_assert(equal(def.values(), s_def.values()));
        internal_assert(equal(def.args(), s_def.args()));
        def.schedule() = s_def.schedule();
        // Append our sub-specializations to the Definition's list
        specializations.insert(specializations.end(), s_def.specializations().begin(), s_def.specializations().end());
    }

    for (size_t i = specializations.size(); i > 0; i--) {
        Expr c = specializations[i-1].condition;
        Definition &s_def = specializations[i-1].definition;
        const EQ *eq = c.as<EQ>();
        const Variable *var = eq ? eq->a.as<Variable>() : c.as<Variable>();

        vector<Definition> s_result = propagate_specialization_in_definition(s_def, name);

        if (var && eq) {
            // Then case
            substitute_value_in_var(var->name, eq->b, s_result);

            // Else case
            if (eq->b.type().is_bool()) {
                substitute_value_in_var(var->name, !eq->b, result);
            }
        } else if (var) {
            // Then case
            substitute_value_in_var(var->name, const_true(), s_result);

            // Else case
            substitute_value_in_var(var->name, const_false(), result);
        } else {
            simplify_using_fact(c, s_result);
            simplify_using_fact(!c, result);
        }

        result.insert(result.end(), s_result.begin(), s_result.end());
    }

    return result;
}

}

void simplify_specializations(map<string, Function> &env) {
    for (auto &iter : env) {
        Function &func = iter.second;
        propagate_specialization_in_definition(func.definition(), func.name());
    }
}

}
}
<commit_msg>Revert previous change<commit_after>#include "SimplifySpecializations.h"
#include "IROperator.h"
#include "IRMutator.h"
#include "Simplify.h"
#include "Substitute.h"
#include "Definition.h"
#include "IREquality.h"

#include <set>

namespace Halide{
namespace Internal {

using std::map;
using std::set;
using std::string;
using std::vector;

namespace {

void substitute_value_in_var(const string &var, Expr value, vector<Definition> &definitions) {
    for (Definition &def : definitions) {
        for (auto &def_arg : def.args()) {
            def_arg = simplify(substitute(var, value, def_arg));
        }
        for (auto &def_val : def.values()) {
            def_val = simplify(substitute(var, value, def_val));
        }
    }
}

class SimplifyUsingFact : public IRMutator {
public:
    using IRMutator::mutate;

    Expr mutate(Expr e) {
        if (e.type().is_bool()) {
            if (equal(fact, e) ||
                can_prove(!fact || e)) {
                // fact implies e
                return const_true();
            }
            if (equal(fact, !e) ||
                equal(!fact, e) ||
                can_prove(!fact || !e)) {
                // fact implies !e
                return const_false();
            }
        }
        return IRMutator::mutate(e);
    }

    Expr fact;
    SimplifyUsingFact(Expr f) : fact(f) {}
};

void simplify_using_fact(Expr fact, vector<Definition> &definitions) {
    for (Definition &def : definitions) {
        for (auto &def_arg : def.args()) {
            def_arg = simplify(SimplifyUsingFact(fact).mutate(def_arg));
        }
        for (auto &def_val : def.values()) {
            def_val = simplify(SimplifyUsingFact(fact).mutate(def_val));
        }
    }
}

vector<Definition> propagate_specialization_in_definition(Definition &def, const string &name) {
    vector<Definition> result;

    result.push_back(def);

    vector<Specialization> &specializations = def.specializations();

    // Prune specializations based on constants:
    // -- Any Specializations that have const-false as a condition
    // can never trigger; go ahead and prune them now to save time & energy
    // during later phases.
    // -- Once we encounter a Specialization that is const-true, no subsequent
    // Specializations can ever trigger (since we evaluate them in order),
    // so erase them.
    bool seen_const_true = false;
    for (auto it = specializations.begin(); it != specializations.end(); /*no-increment*/) {
        Expr old_c = it->condition;
        Expr c = simplify(it->condition);
        // Go ahead and save the simplified condition now
        it->condition = c;
        if (is_zero(c) || seen_const_true) {
            debug(1) << "Erasing unreachable specialization ("
                << old_c << ") -> (" << c << ") for function \"" << name << "\"\n";
            it = specializations.erase(it);
        } else {
            it++;
        }
        seen_const_true |= is_one(c);
    }

    // If the final Specialization is const-true, then the default schedule
    // for the definition will never be run: replace the definition's main
    // schedule with the one from the final Specialization and prune it from
    // the list. This may leave the list of Specializations empty.
    if (!specializations.empty() && is_one(specializations.back().condition)) {
        debug(1) << "Replacing default Schedule with const-true specialization for function \"" << name << "\"\n";
        const Definition s_def = specializations.back().definition;
        specializations.pop_back();

        def.predicate() = s_def.predicate();
        def.values() = s_def.values();
        def.args() = s_def.args();
        def.schedule() = s_def.schedule();
        // Append our sub-specializations to the Definition's list
        specializations.insert(specializations.end(), s_def.specializations().begin(), s_def.specializations().end());
    }

    for (size_t i = specializations.size(); i > 0; i--) {
        Expr c = specializations[i-1].condition;
        Definition &s_def = specializations[i-1].definition;
        const EQ *eq = c.as<EQ>();
        const Variable *var = eq ? eq->a.as<Variable>() : c.as<Variable>();

        vector<Definition> s_result = propagate_specialization_in_definition(s_def, name);

        if (var && eq) {
            // Then case
            substitute_value_in_var(var->name, eq->b, s_result);

            // Else case
            if (eq->b.type().is_bool()) {
                substitute_value_in_var(var->name, !eq->b, result);
            }
        } else if (var) {
            // Then case
            substitute_value_in_var(var->name, const_true(), s_result);

            // Else case
            substitute_value_in_var(var->name, const_false(), result);
        } else {
            simplify_using_fact(c, s_result);
            simplify_using_fact(!c, result);
        }

        result.insert(result.end(), s_result.begin(), s_result.end());
    }

    return result;
}

}

void simplify_specializations(map<string, Function> &env) {
    for (auto &iter : env) {
        Function &func = iter.second;
        propagate_specialization_in_definition(func.definition(), func.name());
    }
}

}
}
<|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "FireSimulator.h"
#include "../World.h"
#include "../BlockID.h"
#include "../Defines.h"
#include "../Chunk.h"
#include "Root.h"
#include "../Bindings/PluginManager.h"

// Easy switch for turning on debugging logging:
#if 0
	#define FLOG LOGD
#else
	#define FLOG(...)
#endif

#define MAX_CHANCE_REPLACE_FUEL 100000
#define MAX_CHANCE_FLAMMABILITY 100000

static const struct
{
	int x, y, z;
} gCrossCoords[] =
{
	{ 1, 0,  0},
	{-1, 0,  0},
	{ 0, 0,  1},
	{ 0, 0, -1},
} ;

static const struct
{
	int x, y, z;
} gNeighborCoords[] =
{
	{ 1,  0,  0},
	{-1,  0,  0},
	{ 0,  1,  0},
	{ 0, -1,  0},
	{ 0,  0,  1},
	{ 0,  0, -1},
} ;

////////////////////////////////////////////////////////////////////////////////
// cFireSimulator:

cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) :
	cSimulator(a_World)
{
	// Read params from the ini file:
	m_BurnStepTimeFuel    = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeFuel",     500);
	m_BurnStepTimeNonfuel = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeNonfuel",  100);
	m_Flammability        = a_IniFile.GetValueSetI("FireSimulator", "Flammability",          50);
	m_ReplaceFuelChance   = a_IniFile.GetValueSetI("FireSimulator", "ReplaceFuelChance",  50000);
}

cFireSimulator::~cFireSimulator()
{
}

void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
	cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();

	int NumMSecs = (int)a_Dt;
	for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
	{
		int x = itr->x;
		int y = itr->y;
		int z = itr->z;
		BLOCKTYPE BlockType = a_Chunk->GetBlock(x, y, z);

		if (!IsAllowedBlock(BlockType))
		{
			// The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire)
			FLOG("FS: Removing block {%d, %d, %d}",
				itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
			);
			itr = Data.erase(itr);
			continue;
		}

		// Try to spread the fire:
		TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z);

		itr->Data -= NumMSecs;
		if (itr->Data >= 0)
		{
			// Not yet, wait for it longer
			++itr;
			continue;
		}

		// Burn out the fire one step by increasing the meta:
		/*
		FLOG("FS: Fire at {%d, %d, %d} is stepping",
			itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
		);
		*/
		NIBBLETYPE BlockMeta = a_Chunk->GetMeta(x, y, z);
		if (BlockMeta == 0x0f)
		{
			// The fire burnt out completely
			FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block",
				itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
			);
			a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
			RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z);
			itr = Data.erase(itr);
			continue;
		}

		if ((itr->y > 0) && (!DoesBurnForever(a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z))))
		{
			a_Chunk->SetMeta(x, y, z, BlockMeta + 1);
		}
		itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z);  // TODO: Add some randomness into this
	}  // for itr - Data[]
}

bool cFireSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
{
	return (a_BlockType == E_BLOCK_FIRE);
}

bool cFireSimulator::IsFuel(BLOCKTYPE a_BlockType)
{
	switch (a_BlockType)
	{
		case E_BLOCK_PLANKS:
		case E_BLOCK_DOUBLE_WOODEN_SLAB:
		case E_BLOCK_WOODEN_SLAB:
		case E_BLOCK_WOODEN_STAIRS:
		case E_BLOCK_SPRUCE_WOOD_STAIRS:
		case E_BLOCK_BIRCH_WOOD_STAIRS:
		case E_BLOCK_JUNGLE_WOOD_STAIRS:
		case E_BLOCK_LEAVES:
		case E_BLOCK_NEW_LEAVES:
		case E_BLOCK_LOG:
		case E_BLOCK_NEW_LOG:
		case E_BLOCK_WOOL:
		case E_BLOCK_BOOKCASE:
		case E_BLOCK_FENCE:
		case E_BLOCK_TNT:
		case E_BLOCK_VINES:
		case E_BLOCK_HAY_BALE:
		case E_BLOCK_TALL_GRASS:
		case E_BLOCK_BIG_FLOWER:
		case E_BLOCK_DANDELION:
		case E_BLOCK_FLOWER:
		case E_BLOCK_CARPET:
		{
			return true;
		}
	}
	return false;
}

bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType)
{
	return (a_BlockType == E_BLOCK_NETHERRACK);
}

void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
{
	if ((a_Chunk == NULL) || !a_Chunk->IsValid())
	{
		return;
	}

	int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
	int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
	BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ);
	if (!IsAllowedBlock(BlockType))
	{
		return;
	}

	// Check for duplicates:
	cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData();
	for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr)
	{
		if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
		{
			// Already present, skip adding
			return;
		}
	}  // for itr - ChunkData[]

	FLOG("FS: Adding block {%d, %d, %d}", a_BlockX, a_BlockY, a_BlockZ);
	ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, 100));
}

int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	bool IsBlockBelowSolid = false;
	if (a_RelY > 0)
	{
		BLOCKTYPE BlockBelow = a_Chunk->GetBlock(a_RelX, a_RelY - 1, a_RelZ);
		if (DoesBurnForever(BlockBelow))
		{
			// Is burning atop of netherrack, burn forever (re-check in 10 sec)
			return 10000;
		}
		if (IsFuel(BlockBelow))
		{
			return m_BurnStepTimeFuel;
		}
		IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow);
	}

	for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
	{
		BLOCKTYPE  BlockType;
		NIBBLETYPE BlockMeta;
		if (a_Chunk->UnboundedRelGetBlock(a_RelX + gCrossCoords[i].x, a_RelY, a_RelZ + gCrossCoords[i].z, BlockType, BlockMeta))
		{
			if (IsFuel(BlockType))
			{
				return m_BurnStepTimeFuel;
			}
		}
	}  // for i - gCrossCoords[]

	if (!IsBlockBelowSolid && (a_RelY >= 0))
	{
		// Checked through everything, nothing was flammable
		// If block below isn't solid, we can't have fire, it would be a non-fueled fire
		// SetBlock just to make sure fire doesn't spawn
		a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0);
		return 0;
	}
	return m_BurnStepTimeNonfuel;
}

void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	/*
	if (m_World.GetTickRandomNumber(10000) > 100)
	{
		// Make the chance to spread 100x smaller
		return;
	}
	*/

	for (int x = a_RelX - 1; x <= a_RelX + 1; x++)
	{
		for (int z = a_RelZ - 1; z <= a_RelZ + 1; z++)
		{
			for (int y = a_RelY - 1; y <= a_RelY + 2; y++)  // flames spread up one more block than around
			{
				// No need to check the coords for equality with the parent block,
				// it cannot catch fire anyway (because it's not an air block)

				if (m_World.GetTickRandomNumber(MAX_CHANCE_FLAMMABILITY) > m_Flammability)
				{
					continue;
				}

				// Start the fire in the neighbor {x, y, z}
				/*
				FLOG("FS: Trying to start fire at {%d, %d, %d}.",
					x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width
				);
				*/
				if (CanStartFireInBlock(a_Chunk, x, y, z))
				{
					int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width;
					int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width;

					if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, ssFireSpread))
					{
						return;
					}

					FLOG("FS: Starting new fire at {%d, %d, %d}.", a_PosX, y, a_PosZ);
					a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0);
				}
			}  // for y
		}  // for z
	}  // for x
}

void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++)
	{
		BLOCKTYPE  BlockType;
		int X = a_RelX + gNeighborCoords[i].x;
		int Z = a_RelZ + gNeighborCoords[i].z;

		cChunkPtr Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(X, Z);
		if (Neighbour == NULL)
		{
			continue;
		}
		BlockType = Neighbour->GetBlock(X, a_RelY + gNeighborCoords[i].y, Z);

		if (!IsFuel(BlockType))
		{
			continue;
		}

		int AbsX = (Neighbour->GetPosX() * cChunkDef::Width) + X;
		int Y = a_RelY + gNeighborCoords[i].y;
		int AbsZ = (Neighbour->GetPosZ() * cChunkDef::Width) + Z;

		if (BlockType == E_BLOCK_TNT)
		{
			m_World.SpawnPrimedTNT(AbsX, Y, AbsZ, 0);
			Neighbour->SetBlock(X, a_RelY + Y, Z, E_BLOCK_AIR, 0);
			return;
		}

		bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance);
		if (ShouldReplaceFuel && !cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, AbsX, Y, AbsZ, ssFireSpread))
		{
			Neighbour->SetBlock(X, Y, Z, E_BLOCK_FIRE, 0);
		}
		else
		{
			Neighbour->SetBlock(X, Y, Z, E_BLOCK_AIR, 0);
		}
	}  // for i - Coords[]
}

bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ)
{
	BLOCKTYPE  BlockType;
	NIBBLETYPE BlockMeta;
	if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta))
	{
		// The chunk is not accessible
		return false;
	}

	if (BlockType != E_BLOCK_AIR)
	{
		// Only an air block can be replaced by a fire block
		return false;
	}

	for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++)
	{
		if (!a_NearChunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta))
		{
			// Neighbor inaccessible, skip it while evaluating
			continue;
		}
		if (IsFuel(BlockType))
		{
			return true;
		}
	}  // for i - Coords[]
	return false;
}

<commit_msg>Added blocks to the fire simulator<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "FireSimulator.h"
#include "../World.h"
#include "../BlockID.h"
#include "../Defines.h"
#include "../Chunk.h"
#include "Root.h"
#include "../Bindings/PluginManager.h"

// Easy switch for turning on debugging logging:
#if 0
	#define FLOG LOGD
#else
	#define FLOG(...)
#endif

#define MAX_CHANCE_REPLACE_FUEL 100000
#define MAX_CHANCE_FLAMMABILITY 100000

static const struct
{
	int x, y, z;
} gCrossCoords[] =
{
	{ 1, 0,  0},
	{-1, 0,  0},
	{ 0, 0,  1},
	{ 0, 0, -1},
} ;

static const struct
{
	int x, y, z;
} gNeighborCoords[] =
{
	{ 1,  0,  0},
	{-1,  0,  0},
	{ 0,  1,  0},
	{ 0, -1,  0},
	{ 0,  0,  1},
	{ 0,  0, -1},
} ;

////////////////////////////////////////////////////////////////////////////////
// cFireSimulator:

cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) :
	cSimulator(a_World)
{
	// Read params from the ini file:
	m_BurnStepTimeFuel    = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeFuel",     500);
	m_BurnStepTimeNonfuel = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeNonfuel",  100);
	m_Flammability        = a_IniFile.GetValueSetI("FireSimulator", "Flammability",          50);
	m_ReplaceFuelChance   = a_IniFile.GetValueSetI("FireSimulator", "ReplaceFuelChance",  50000);
}

cFireSimulator::~cFireSimulator()
{
}

void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
	cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();

	int NumMSecs = (int)a_Dt;
	for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
	{
		int x = itr->x;
		int y = itr->y;
		int z = itr->z;
		BLOCKTYPE BlockType = a_Chunk->GetBlock(x, y, z);

		if (!IsAllowedBlock(BlockType))
		{
			// The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire)
			FLOG("FS: Removing block {%d, %d, %d}",
				itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
			);
			itr = Data.erase(itr);
			continue;
		}

		// Try to spread the fire:
		TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z);

		itr->Data -= NumMSecs;
		if (itr->Data >= 0)
		{
			// Not yet, wait for it longer
			++itr;
			continue;
		}

		// Burn out the fire one step by increasing the meta:
		/*
		FLOG("FS: Fire at {%d, %d, %d} is stepping",
			itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
		);
		*/
		NIBBLETYPE BlockMeta = a_Chunk->GetMeta(x, y, z);
		if (BlockMeta == 0x0f)
		{
			// The fire burnt out completely
			FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block",
				itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
			);
			a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
			RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z);
			itr = Data.erase(itr);
			continue;
		}

		if ((itr->y > 0) && (!DoesBurnForever(a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z))))
		{
			a_Chunk->SetMeta(x, y, z, BlockMeta + 1);
		}
		itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z);  // TODO: Add some randomness into this
	}  // for itr - Data[]
}

bool cFireSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
{
	return (a_BlockType == E_BLOCK_FIRE);
}

bool cFireSimulator::IsFuel(BLOCKTYPE a_BlockType)
{
	switch (a_BlockType)
	{
		case E_BLOCK_PLANKS:
		case E_BLOCK_DOUBLE_WOODEN_SLAB:
		case E_BLOCK_WOODEN_SLAB:
		case E_BLOCK_WOODEN_STAIRS:
		case E_BLOCK_SPRUCE_WOOD_STAIRS:
		case E_BLOCK_BIRCH_WOOD_STAIRS:
		case E_BLOCK_JUNGLE_WOOD_STAIRS:
		case E_BLOCK_LEAVES:
		case E_BLOCK_NEW_LEAVES:
		case E_BLOCK_LOG:
		case E_BLOCK_NEW_LOG:
		case E_BLOCK_WOOL:
		case E_BLOCK_BOOKCASE:
		case E_BLOCK_FENCE:
		case E_BLOCK_SPRUCE_FENCE:
		case E_BLOCK_BIRCH_FENCE:
		case E_BLOCK_JUNGLE_FENCE:
		case E_BLOCK_DARK_OAK_FENCE:
		case E_BLOCK_ACACIA_FENCE:
		case E_BLOCK_FENCE_GATE:
		case E_BLOCK_SPRUCE_FENCE_GATE:
		case E_BLOCK_BIRCH_FENCE_GATE:
		case E_BLOCK_JUNGLE_FENCE_GATE:
		case E_BLOCK_DARK_OAK_FENCE_GATE:
		case E_BLOCK_ACACIA_FENCE_GATE:
		case E_BLOCK_TNT:
		case E_BLOCK_VINES:
		case E_BLOCK_HAY_BALE:
		case E_BLOCK_TALL_GRASS:
		case E_BLOCK_BIG_FLOWER:
		case E_BLOCK_DANDELION:
		case E_BLOCK_FLOWER:
		case E_BLOCK_CARPET:
		{
			return true;
		}
	}
	return false;
}

bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType)
{
	return (a_BlockType == E_BLOCK_NETHERRACK);
}

void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
{
	if ((a_Chunk == NULL) || !a_Chunk->IsValid())
	{
		return;
	}

	int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
	int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
	BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ);
	if (!IsAllowedBlock(BlockType))
	{
		return;
	}

	// Check for duplicates:
	cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData();
	for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr)
	{
		if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
		{
			// Already present, skip adding
			return;
		}
	}  // for itr - ChunkData[]

	FLOG("FS: Adding block {%d, %d, %d}", a_BlockX, a_BlockY, a_BlockZ);
	ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, 100));
}

int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	bool IsBlockBelowSolid = false;
	if (a_RelY > 0)
	{
		BLOCKTYPE BlockBelow = a_Chunk->GetBlock(a_RelX, a_RelY - 1, a_RelZ);
		if (DoesBurnForever(BlockBelow))
		{
			// Is burning atop of netherrack, burn forever (re-check in 10 sec)
			return 10000;
		}
		if (IsFuel(BlockBelow))
		{
			return m_BurnStepTimeFuel;
		}
		IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow);
	}

	for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
	{
		BLOCKTYPE  BlockType;
		NIBBLETYPE BlockMeta;
		if (a_Chunk->UnboundedRelGetBlock(a_RelX + gCrossCoords[i].x, a_RelY, a_RelZ + gCrossCoords[i].z, BlockType, BlockMeta))
		{
			if (IsFuel(BlockType))
			{
				return m_BurnStepTimeFuel;
			}
		}
	}  // for i - gCrossCoords[]

	if (!IsBlockBelowSolid && (a_RelY >= 0))
	{
		// Checked through everything, nothing was flammable
		// If block below isn't solid, we can't have fire, it would be a non-fueled fire
		// SetBlock just to make sure fire doesn't spawn
		a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0);
		return 0;
	}
	return m_BurnStepTimeNonfuel;
}

void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	/*
	if (m_World.GetTickRandomNumber(10000) > 100)
	{
		// Make the chance to spread 100x smaller
		return;
	}
	*/

	for (int x = a_RelX - 1; x <= a_RelX + 1; x++)
	{
		for (int z = a_RelZ - 1; z <= a_RelZ + 1; z++)
		{
			for (int y = a_RelY - 1; y <= a_RelY + 2; y++)  // flames spread up one more block than around
			{
				// No need to check the coords for equality with the parent block,
				// it cannot catch fire anyway (because it's not an air block)

				if (m_World.GetTickRandomNumber(MAX_CHANCE_FLAMMABILITY) > m_Flammability)
				{
					continue;
				}

				// Start the fire in the neighbor {x, y, z}
				/*
				FLOG("FS: Trying to start fire at {%d, %d, %d}.",
					x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width
				);
				*/
				if (CanStartFireInBlock(a_Chunk, x, y, z))
				{
					int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width;
					int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width;

					if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, ssFireSpread))
					{
						return;
					}

					FLOG("FS: Starting new fire at {%d, %d, %d}.", a_PosX, y, a_PosZ);
					a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0);
				}
			}  // for y
		}  // for z
	}  // for x
}

void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
	for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++)
	{
		BLOCKTYPE  BlockType;
		int X = a_RelX + gNeighborCoords[i].x;
		int Z = a_RelZ + gNeighborCoords[i].z;

		cChunkPtr Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(X, Z);
		if (Neighbour == NULL)
		{
			continue;
		}
		BlockType = Neighbour->GetBlock(X, a_RelY + gNeighborCoords[i].y, Z);

		if (!IsFuel(BlockType))
		{
			continue;
		}

		int AbsX = (Neighbour->GetPosX() * cChunkDef::Width) + X;
		int Y = a_RelY + gNeighborCoords[i].y;
		int AbsZ = (Neighbour->GetPosZ() * cChunkDef::Width) + Z;

		if (BlockType == E_BLOCK_TNT)
		{
			m_World.SpawnPrimedTNT(AbsX, Y, AbsZ, 0);
			Neighbour->SetBlock(X, a_RelY + Y, Z, E_BLOCK_AIR, 0);
			return;
		}

		bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance);
		if (ShouldReplaceFuel && !cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, AbsX, Y, AbsZ, ssFireSpread))
		{
			Neighbour->SetBlock(X, Y, Z, E_BLOCK_FIRE, 0);
		}
		else
		{
			Neighbour->SetBlock(X, Y, Z, E_BLOCK_AIR, 0);
		}
	}  // for i - Coords[]
}

bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ)
{
	BLOCKTYPE  BlockType;
	NIBBLETYPE BlockMeta;
	if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta))
	{
		// The chunk is not accessible
		return false;
	}

	if (BlockType != E_BLOCK_AIR)
	{
		// Only an air block can be replaced by a fire block
		return false;
	}

	for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++)
	{
		if (!a_NearChunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta))
		{
			// Neighbor inaccessible, skip it while evaluating
			continue;
		}
		if (IsFuel(BlockType))
		{
			return true;
		}
	}  // for i - Coords[]
	return false;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/compiler/lib/java/util.h>

namespace apache {
namespace thrift {
namespace compiler {
namespace java {

std::string mangle_java_name(const std::string& ref, bool capitalize) {
  std::ostringstream res;
  // When we are capitalizing, initialize upCase to true in order to force first
  // character to upper case
  bool upcase = capitalize;
  // On the other hand, force first character to lowercase, unless both first
  // AND second characters are uppercase (this is so we don't mess up any
  // poorly-named method that might start with acronyms)
  bool acronym = ref.size() > 1 && std::isupper(ref[0]) && std::isupper(ref[1]);
  bool downcase = !capitalize && !acronym;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    if (ref[i] == '_') {
      upcase = true;
      continue;
    } else {
      char ch = ref[i];
      if (downcase) {
        ch = std::tolower(ch);
      }
      if (upcase) {
        ch = std::toupper(ch);
      }
      res << ch;
      upcase = false;
      downcase = false;
    }
  }
  return res.str();
}

std::string mangle_java_constant_name(const std::string& ref) {
  std::ostringstream res;
  bool lowercase = false;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    char ch = ref[i];
    if (std::isupper(ch)) {
      if (lowercase) {
        res << '_';
      }
      res << static_cast<char>(std::toupper(ch));
      lowercase = false;
    } else if (std::islower(ch)) {
      res << static_cast<char>(std::toupper(ch));
      lowercase = true;
    } else {
      // Not a letter, just emit it
      res << ch;
    }
  }
  return res.str();
}

std::string quote_java_string(const std::string& unescaped) {
  std::ostringstream quoted;
  quoted << '\"';
  for (std::string::size_type i = 0; i < unescaped.size();) {
    switch (unescaped[i]) {
      case '\\': {
        quoted << unescaped[i];
        ++i;
        assert(i <= unescaped.size());
        if (i == unescaped.size()) {
          throw std::runtime_error(
              "compiler error: leading backslash missing escape sequence: " +
              unescaped);
        }
        if (unescaped[i] == 'x') {
          auto end = unescaped.find_first_not_of("0123456789abcdefABCDEF", ++i);
          if (end == std::string::npos) {
            end = unescaped.size();
          }
          if (end == i) {
            throw std::runtime_error(
                "compiler error: missing hexadecimal character code in escape sequence: " +
                unescaped);
          }
          assert(i < end);
          if (end > i + 2) {
            end = i + 2;
          }
          quoted << 'u';
          for (auto n = 4 - (end - i); n--;) {
            quoted << '0';
          }
          quoted.write(std::next(unescaped.data(), i), end - i);
          i = end;
        } else {
          quoted << unescaped[i++];
        }
        break;
      }
      case '"':
        quoted << '\\' << unescaped[i];
        ++i;
        break;
      default:
        quoted << unescaped[i];
        ++i;
        break;
    }
  }
  quoted << '\"';

  return quoted.str();
}

std::string package_to_path(std::string package) {
  if (boost::algorithm::contains(package, "/")) {
    std::ostringstream err;
    err << "\"" << package << "\" is not a valid Java package name";
    throw std::runtime_error{err.str()};
  }
  boost::algorithm::replace_all(package, ".", "/");
  return package;
}
} // namespace java
} // namespace compiler
} // namespace thrift
} // namespace apache
<commit_msg>thrift: add missing cctype include for std::tolower<commit_after>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/compiler/lib/java/util.h>

#include <cctype>

namespace apache {
namespace thrift {
namespace compiler {
namespace java {

std::string mangle_java_name(const std::string& ref, bool capitalize) {
  std::ostringstream res;
  // When we are capitalizing, initialize upCase to true in order to force first
  // character to upper case
  bool upcase = capitalize;
  // On the other hand, force first character to lowercase, unless both first
  // AND second characters are uppercase (this is so we don't mess up any
  // poorly-named method that might start with acronyms)
  bool acronym = ref.size() > 1 && std::isupper(ref[0]) && std::isupper(ref[1]);
  bool downcase = !capitalize && !acronym;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    if (ref[i] == '_') {
      upcase = true;
      continue;
    } else {
      char ch = ref[i];
      if (downcase) {
        ch = std::tolower(ch);
      }
      if (upcase) {
        ch = std::toupper(ch);
      }
      res << ch;
      upcase = false;
      downcase = false;
    }
  }
  return res.str();
}

std::string mangle_java_constant_name(const std::string& ref) {
  std::ostringstream res;
  bool lowercase = false;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    char ch = ref[i];
    if (std::isupper(ch)) {
      if (lowercase) {
        res << '_';
      }
      res << static_cast<char>(std::toupper(ch));
      lowercase = false;
    } else if (std::islower(ch)) {
      res << static_cast<char>(std::toupper(ch));
      lowercase = true;
    } else {
      // Not a letter, just emit it
      res << ch;
    }
  }
  return res.str();
}

std::string quote_java_string(const std::string& unescaped) {
  std::ostringstream quoted;
  quoted << '\"';
  for (std::string::size_type i = 0; i < unescaped.size();) {
    switch (unescaped[i]) {
      case '\\': {
        quoted << unescaped[i];
        ++i;
        assert(i <= unescaped.size());
        if (i == unescaped.size()) {
          throw std::runtime_error(
              "compiler error: leading backslash missing escape sequence: " +
              unescaped);
        }
        if (unescaped[i] == 'x') {
          auto end = unescaped.find_first_not_of("0123456789abcdefABCDEF", ++i);
          if (end == std::string::npos) {
            end = unescaped.size();
          }
          if (end == i) {
            throw std::runtime_error(
                "compiler error: missing hexadecimal character code in escape sequence: " +
                unescaped);
          }
          assert(i < end);
          if (end > i + 2) {
            end = i + 2;
          }
          quoted << 'u';
          for (auto n = 4 - (end - i); n--;) {
            quoted << '0';
          }
          quoted.write(std::next(unescaped.data(), i), end - i);
          i = end;
        } else {
          quoted << unescaped[i++];
        }
        break;
      }
      case '"':
        quoted << '\\' << unescaped[i];
        ++i;
        break;
      default:
        quoted << unescaped[i];
        ++i;
        break;
    }
  }
  quoted << '\"';

  return quoted.str();
}

std::string package_to_path(std::string package) {
  if (boost::algorithm::contains(package, "/")) {
    std::ostringstream err;
    err << "\"" << package << "\" is not a valid Java package name";
    throw std::runtime_error{err.str()};
  }
  boost::algorithm::replace_all(package, ".", "/");
  return package;
}
} // namespace java
} // namespace compiler
} // namespace thrift
} // namespace apache
<|endoftext|>


<commit_before>#include "Script.hpp"

#include <angelscript.h>
#include <cstring>

#include "../Manager/Managers.hpp"
#include "../Manager/ScriptManager.hpp"
#include "../Manager/ResourceManager.hpp"
#include "../Entity/Entity.hpp"
#include "../Script/ScriptFile.hpp"

using namespace Component;

Script::Script() {

}

Script::~Script() {
    if (instance != nullptr)
        instance->Release();

    if (scriptFile != nullptr)
        Managers().resourceManager->FreeScriptFile(scriptFile);

    ClearPropertyMap();

}

Json::Value Script::Save() const {
    Json::Value component;
    if (scriptFile != nullptr)
        component["scriptName"] = scriptFile->path + scriptFile->name;

    for (auto &nameProperty : propertyMap) {

        const std::string& name = nameProperty.first;
        int typeId = nameProperty.second->typeID;
        void* varPointer = nameProperty.second->data;
        int size = nameProperty.second->size;

        for (int i = 0; i < size; i++)
            component["propertyMap"][name][std::to_string(typeId)][i] = ((unsigned char*)varPointer)[i];

    }
    return component;
}

void Script::AddToPropertyMap(std::string &name, int type, int size, void* data) {

    if(!IsInPropertyMap(name, type))
        propertyMap[name] = new Property(type, size, data);

}

void Script::CopyDataFromPropertyMap(const std::string &name, void* target){

    std::memcpy(target, propertyMap[name]->data, propertyMap[name]->size);

}

void* Script::GetDataFromPropertyMap(const std::string &name){

    return propertyMap[name]->data;

}

bool Script::IsInPropertyMap(const std::string &name, int type) {

    auto it = propertyMap.find(name);

    if (it != propertyMap.end() && it->second->typeID == type)
        return true;

    return false;

}

/// Clears the property map.
void Script::ClearPropertyMap() {

    for(auto pair : propertyMap)
        delete pair.second;

    propertyMap.clear();

}<commit_msg>Fixed code to match code standard<commit_after>#include "Script.hpp"

#include <angelscript.h>
#include <cstring>

#include "../Manager/Managers.hpp"
#include "../Manager/ScriptManager.hpp"
#include "../Manager/ResourceManager.hpp"
#include "../Entity/Entity.hpp"
#include "../Script/ScriptFile.hpp"

using namespace Component;

Script::Script() {

}

Script::~Script() {
    if (instance != nullptr)
        instance->Release();

    if (scriptFile != nullptr)
        Managers().resourceManager->FreeScriptFile(scriptFile);

    ClearPropertyMap();

}

Json::Value Script::Save() const {
    Json::Value component;
    if (scriptFile != nullptr)
        component["scriptName"] = scriptFile->path + scriptFile->name;

    for (auto &nameProperty : propertyMap) {

        const std::string& name = nameProperty.first;
        int typeId = nameProperty.second->typeID;
        void* varPointer = nameProperty.second->data;
        int size = nameProperty.second->size;

        for (int i = 0; i < size; i++)
            component["propertyMap"][name][std::to_string(typeId)][i] = ((unsigned char*)varPointer)[i];

    }
    return component;
}

void Script::AddToPropertyMap(std::string &name, int type, int size, void* data) {

    if (!IsInPropertyMap(name, type))
        propertyMap[name] = new Property(type, size, data);

}

void Script::CopyDataFromPropertyMap(const std::string &name, void* target){

    std::memcpy(target, propertyMap[name]->data, propertyMap[name]->size);

}

void* Script::GetDataFromPropertyMap(const std::string &name){

    return propertyMap[name]->data;

}

bool Script::IsInPropertyMap(const std::string &name, int type) {

    auto it = propertyMap.find(name);

    if (it != propertyMap.end() && it->second->typeID == type)
        return true;

    return false;

}

/// Clears the property map.
void Script::ClearPropertyMap() {

    for (auto pair : propertyMap)
        delete pair.second;

    propertyMap.clear();

}<|endoftext|>