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

#define _SVARRAY_CXX

#define _SVSTDARR_BOOLS
#define _SVSTDARR_BYTES
#define _SVSTDARR_ULONGS
#define _SVSTDARR_USHORTS
#define _SVSTDARR_LONGS
#define _SVSTDARR_SHORTS
#define _SVSTDARR_STRINGS
#define _SVSTDARR_STRINGSDTOR
#define _SVSTDARR_STRINGSSORT
#define _SVSTDARR_STRINGSSORTDTOR
#define _SVSTDARR_STRINGSISORT
#define _SVSTDARR_STRINGSISORTDTOR
#define _SVSTDARR_USHORTSSORT

#define _SVSTDARR_BYTESTRINGS
#define _SVSTDARR_BYTESTRINGSDTOR
#define _SVSTDARR_BYTESTRINGSSORT
#define _SVSTDARR_BYTESTRINGSSORTDTOR
#define _SVSTDARR_BYTESTRINGSISORT
#define _SVSTDARR_BYTESTRINGSISORTDTOR

#define _SVSTDARR_XUB_STRLEN

#include <svstdarr.hxx>

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifdef MAC
#pragma segment NEVER_PURGE
#endif

SV_IMPL_VARARR(SvPtrarr,VoidPtr)
SV_IMPL_VARARR_PLAIN(SvPtrarrPlain,VoidPtr)

USHORT SvPtrarr::GetPos( const VoidPtr& aElement ) const
{   USHORT n;
    for( n=0; n < nA && *(GetData()+n) != aElement; ) n++;
    return ( n >= nA ? USHRT_MAX : n );
}

USHORT SvPtrarrPlain::GetPos( const VoidPtr aElement ) const
{   USHORT n;
    for( n=0; n < nA && *(GetData()+n) != aElement; ) n++;
    return ( n >= nA ? USHRT_MAX : n );
}

SV_IMPL_VARARR( SvBools, BOOL )
SV_IMPL_VARARR( SvBytes, BYTE )
SV_IMPL_VARARR( SvULongs, ULONG )
SV_IMPL_VARARR( SvUShorts, USHORT )
SV_IMPL_VARARR( SvLongs, long)
SV_IMPL_VARARR( SvShorts, short )

SV_IMPL_VARARR( SvXub_StrLens, xub_StrLen )

SV_IMPL_PTRARR( SvStrings, StringPtr )
SV_IMPL_PTRARR( SvStringsDtor, StringPtr )
SV_IMPL_OP_PTRARR_SORT( SvStringsSort, StringPtr )
SV_IMPL_OP_PTRARR_SORT( SvStringsSortDtor, StringPtr )

SV_IMPL_PTRARR( SvByteStrings, ByteStringPtr )
SV_IMPL_PTRARR( SvByteStringsDtor, ByteStringPtr )
SV_IMPL_OP_PTRARR_SORT( SvByteStringsSort, ByteStringPtr )
SV_IMPL_OP_PTRARR_SORT( SvByteStringsSortDtor, ByteStringPtr )

// ---------------- strings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvStringsISort, StringPtr )
void SvStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((StringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvStringsISort::Seek_Entry( const StringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvStringsISort_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((StringPtr*)pData + nM))->
                                        CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// ---------------- strings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvStringsISortDtor, StringPtr )
void SvStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((StringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvStringsISortDtor::Seek_Entry( const StringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvStringsISortDtor_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((StringPtr*)pData + nM))->
                                    CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// ---------------- Ushorts -------------------------------------

/* SortArray fuer UShorts */
BOOL SvUShortsSort::Seek_Entry( const USHORT aE, USHORT* pP ) const
{
    register USHORT nO  = SvUShorts::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            if( *(pData + nM) == aE )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( *(pData + nM) < aE )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

void SvUShortsSort::Insert( const SvUShortsSort * pI, USHORT nS, USHORT nE )
{
    if( USHRT_MAX == nE )
        nE = pI->Count();
    USHORT nP;
    const USHORT * pIArr = pI->GetData();
    for( ; nS < nE; ++nS )
    {
        if( ! Seek_Entry( *(pIArr+nS), &nP) )
                SvUShorts::Insert( *(pIArr+nS), nP );
        if( ++nP >= Count() )
        {
            SvUShorts::Insert( pI, nP, nS+1, nE );
            nS = nE;
        }
    }
}

BOOL SvUShortsSort::Insert( const USHORT aE )
{
    USHORT nP;
    BOOL bExist;
    if( ! ( bExist = Seek_Entry( aE, &nP ) ) )
        SvUShorts::Insert( aE, nP );
    return !bExist;
}

BOOL SvUShortsSort::Insert( const USHORT aE, USHORT& rP )
{
    BOOL bExist;
    if( ! ( bExist = Seek_Entry( aE, &rP ) ) )
        SvUShorts::Insert( aE, rP );
    return !bExist;
}

void SvUShortsSort::Insert( const USHORT* pE, USHORT nL)
{
    USHORT nP;
    for( USHORT n = 0; n < nL; ++n )
        if( ! Seek_Entry( *(pE+n), &nP ))
            SvUShorts::Insert( *(pE+n), nP );
}

// remove ab Pos
void SvUShortsSort::RemoveAt( const USHORT nP, USHORT nL )
{
    if( nL )
        SvUShorts::Remove( nP, nL);
}

// remove ab dem Eintrag
void SvUShortsSort::Remove( const USHORT aE, USHORT nL )
{
    USHORT nP;
    if( nL && Seek_Entry( aE, &nP ) )
        SvUShorts::Remove( nP, nL);
}

// ---------------- bytestrings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvByteStringsISort, ByteStringPtr )
void SvByteStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((ByteStringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvByteStringsISort::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvByteStringsISort_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
                        CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvByteStringsISortDtor, ByteStringPtr )
void SvByteStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((ByteStringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvByteStringsISortDtor::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvByteStringsISortDtor_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
                                    CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

<commit_msg>new standard arrays<commit_after>/*************************************************************************
 *
 *  $RCSfile: svarray.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: jp $ $Date: 2001-03-20 18:31:40 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#define _SVARRAY_CXX

#define _SVSTDARR_BOOLS
#define _SVSTDARR_BYTES
#define _SVSTDARR_ULONGS
#define _SVSTDARR_ULONGSSORT
#define _SVSTDARR_USHORTS
#define _SVSTDARR_LONGS
#define _SVSTDARR_LONGSSORT
#define _SVSTDARR_SHORTS
#define _SVSTDARR_STRINGS
#define _SVSTDARR_STRINGSDTOR
#define _SVSTDARR_STRINGSSORT
#define _SVSTDARR_STRINGSSORTDTOR
#define _SVSTDARR_STRINGSISORT
#define _SVSTDARR_STRINGSISORTDTOR
#define _SVSTDARR_USHORTSSORT

#define _SVSTDARR_BYTESTRINGS
#define _SVSTDARR_BYTESTRINGSDTOR
#define _SVSTDARR_BYTESTRINGSSORT
#define _SVSTDARR_BYTESTRINGSSORTDTOR
#define _SVSTDARR_BYTESTRINGSISORT
#define _SVSTDARR_BYTESTRINGSISORTDTOR

#define _SVSTDARR_XUB_STRLEN
#define _SVSTDARR_XUB_STRLENSORT

#include <svstdarr.hxx>

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifdef MAC
#pragma segment NEVER_PURGE
#endif

SV_IMPL_VARARR(SvPtrarr,VoidPtr)
SV_IMPL_VARARR_PLAIN(SvPtrarrPlain,VoidPtr)

USHORT SvPtrarr::GetPos( const VoidPtr& aElement ) const
{   USHORT n;
    for( n=0; n < nA && *(GetData()+n) != aElement; ) n++;
    return ( n >= nA ? USHRT_MAX : n );
}

USHORT SvPtrarrPlain::GetPos( const VoidPtr aElement ) const
{   USHORT n;
    for( n=0; n < nA && *(GetData()+n) != aElement; ) n++;
    return ( n >= nA ? USHRT_MAX : n );
}

SV_IMPL_VARARR( SvBools, BOOL )
SV_IMPL_VARARR( SvBytes, BYTE )
SV_IMPL_VARARR( SvULongs, ULONG )
SV_IMPL_VARARR( SvUShorts, USHORT )
SV_IMPL_VARARR( SvLongs, long)
SV_IMPL_VARARR( SvShorts, short )

SV_IMPL_VARARR_SORT( SvULongsSort, ULONG )
SV_IMPL_VARARR_SORT( SvLongsSort, long )
SV_IMPL_VARARR_SORT( SvXub_StrLensSort, xub_StrLen )

SV_IMPL_VARARR( SvXub_StrLens, xub_StrLen )

SV_IMPL_PTRARR( SvStrings, StringPtr )
SV_IMPL_PTRARR( SvStringsDtor, StringPtr )
SV_IMPL_OP_PTRARR_SORT( SvStringsSort, StringPtr )
SV_IMPL_OP_PTRARR_SORT( SvStringsSortDtor, StringPtr )

SV_IMPL_PTRARR( SvByteStrings, ByteStringPtr )
SV_IMPL_PTRARR( SvByteStringsDtor, ByteStringPtr )
SV_IMPL_OP_PTRARR_SORT( SvByteStringsSort, ByteStringPtr )
SV_IMPL_OP_PTRARR_SORT( SvByteStringsSortDtor, ByteStringPtr )

// ---------------- strings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvStringsISort, StringPtr )
void SvStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((StringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvStringsISort::Seek_Entry( const StringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvStringsISort_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((StringPtr*)pData + nM))->
                                        CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// ---------------- strings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvStringsISortDtor, StringPtr )
void SvStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((StringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvStringsISortDtor::Seek_Entry( const StringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvStringsISortDtor_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((StringPtr*)pData + nM))->
                                    CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// ---------------- Ushorts -------------------------------------

/* SortArray fuer UShorts */
BOOL SvUShortsSort::Seek_Entry( const USHORT aE, USHORT* pP ) const
{
    register USHORT nO  = SvUShorts::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            if( *(pData + nM) == aE )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( *(pData + nM) < aE )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

void SvUShortsSort::Insert( const SvUShortsSort * pI, USHORT nS, USHORT nE )
{
    if( USHRT_MAX == nE )
        nE = pI->Count();
    USHORT nP;
    const USHORT * pIArr = pI->GetData();
    for( ; nS < nE; ++nS )
    {
        if( ! Seek_Entry( *(pIArr+nS), &nP) )
                SvUShorts::Insert( *(pIArr+nS), nP );
        if( ++nP >= Count() )
        {
            SvUShorts::Insert( pI, nP, nS+1, nE );
            nS = nE;
        }
    }
}

BOOL SvUShortsSort::Insert( const USHORT aE )
{
    USHORT nP;
    BOOL bExist;
    if( ! ( bExist = Seek_Entry( aE, &nP ) ) )
        SvUShorts::Insert( aE, nP );
    return !bExist;
}

BOOL SvUShortsSort::Insert( const USHORT aE, USHORT& rP )
{
    BOOL bExist;
    if( ! ( bExist = Seek_Entry( aE, &rP ) ) )
        SvUShorts::Insert( aE, rP );
    return !bExist;
}

void SvUShortsSort::Insert( const USHORT* pE, USHORT nL)
{
    USHORT nP;
    for( USHORT n = 0; n < nL; ++n )
        if( ! Seek_Entry( *(pE+n), &nP ))
            SvUShorts::Insert( *(pE+n), nP );
}

// remove ab Pos
void SvUShortsSort::RemoveAt( const USHORT nP, USHORT nL )
{
    if( nL )
        SvUShorts::Remove( nP, nL);
}

// remove ab dem Eintrag
void SvUShortsSort::Remove( const USHORT aE, USHORT nL )
{
    USHORT nP;
    if( nL && Seek_Entry( aE, &nP ) )
        SvUShorts::Remove( nP, nL);
}

// ---------------- bytestrings -------------------------------------

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvByteStringsISort, ByteStringPtr )
void SvByteStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((ByteStringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvByteStringsISort::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvByteStringsISort_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
                        CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

// Array mit anderer Seek-Methode!
_SV_IMPL_SORTAR_ALG( SvByteStringsISortDtor, ByteStringPtr )
void SvByteStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL )
{
    if( nL )
    {
        DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
        for( USHORT n=nP; n < nP + nL; n++ )
            delete *((ByteStringPtr*)pData+n);
        SvPtrarr::Remove( nP, nL );
    }
}
BOOL SvByteStringsISortDtor::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const
{
    register USHORT nO  = SvByteStringsISortDtor_SAR::Count(),
            nM,
            nU = 0;
    if( nO > 0 )
    {
        nO--;
        while( nU <= nO )
        {
            nM = nU + ( nO - nU ) / 2;
            StringCompare eCmp = (*((ByteStringPtr*)pData + nM))->
                                    CompareIgnoreCaseToAscii( *(aE) );
            if( COMPARE_EQUAL == eCmp )
            {
                if( pP ) *pP = nM;
                return TRUE;
            }
            else if( COMPARE_LESS == eCmp )
                nU = nM + 1;
            else if( nM == 0 )
            {
                if( pP ) *pP = nU;
                return FALSE;
            }
            else
                nO = nM - 1;
        }
    }
    if( pP ) *pP = nU;
    return FALSE;
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#define UNICODE
#define _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <prewin.h>
#include <tchar.h>
#include <postwin.h>
#include <stdio.h>
#include <systools/win32/uwinapi.h>
#include <sal/macros.h>

// need to undef min and max macros from MS headers here to make
// the std::min and std::max from stl visible again
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif

#include "docrecovery.hxx"

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

static LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData )
{
    HKEY    hKey = NULL;
    LONG    lResult;

    lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );

    if ( ERROR_SUCCESS == lResult )
    {
        lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData );
        RegCloseKey( hKey );
    }

    return lResult;
}

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

static LONG RegWriteValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData )
{
    HKEY    hKey = NULL;
    LONG    lResult;

    lResult = RegCreateKeyEx( hBaseKey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );

    if ( ERROR_SUCCESS == lResult )
    {
        lResult = RegSetValueEx( hKey, lpValueName, NULL, dwType, (CONST sal_uInt8 *)lpData, cbData );
        RegCloseKey( hKey );
    }

    return lResult;
}

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

namespace svx{
    namespace DocRecovery{

        bool ErrorRepSendDialog::ReadParams()
        {
            _TCHAR  szBuffer[2048];

            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyServer"),
                szBuffer,
                sizeof(szBuffer) ) )
                maParams.maHTTPProxyServer = (sal_Unicode *)szBuffer;

            DWORD   dwProxyPort;
            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyPort"),
                &dwProxyPort,
                sizeof(dwProxyPort) ) )
            {
                _stprintf( szBuffer, _T("%d"), dwProxyPort );
                maParams.maHTTPProxyPort = (sal_Unicode *)szBuffer;
            }

            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("ReturnAddress"),
                szBuffer,
                sizeof(szBuffer) ) )
                maEMailAddrED.SetText( (sal_Unicode *)szBuffer );

            DWORD   fAllowContact = sal_False;
            RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("AllowContact"),
                &fAllowContact,
                sizeof(fAllowContact) );
            maContactCB.Check( (sal_Bool)fAllowContact );

            DWORD   uInternetConnection = 0;
            RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPConnection"),
                &uInternetConnection,
                sizeof(uInternetConnection) );
            maParams.miHTTPConnectionType = uInternetConnection;

            return true;
        }

        bool ErrorRepSendDialog::SaveParams()
        {
            const _TCHAR    *lpHTTPProxyServer = reinterpret_cast<LPCTSTR>(maParams.maHTTPProxyServer.GetBuffer());
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyServer"), REG_SZ,
                lpHTTPProxyServer,
                sizeof(TCHAR) * (_tcslen(lpHTTPProxyServer) + 1) );

            _TCHAR* endptr = NULL;
            DWORD dwProxyPort = _tcstoul( reinterpret_cast<LPCTSTR>(maParams.maHTTPProxyPort.GetBuffer()), &endptr, 10 );

            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyPort"), REG_DWORD,
                &dwProxyPort,
                sizeof(DWORD) );

            DWORD   fAllowContact = IsContactAllowed();
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("AllowContact"), REG_DWORD,
                &fAllowContact,
                sizeof(DWORD) );

            DWORD uInternetConnection = maParams.miHTTPConnectionType;

            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPConnection"), REG_DWORD,
                &uInternetConnection,
                sizeof(DWORD) );

            const _TCHAR    *lpEmail = reinterpret_cast<LPCTSTR>(GetEMailAddress().GetBuffer());
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("ReturnAddress"), REG_SZ,
                lpEmail,
                sizeof(TCHAR) * (_tcslen(lpEmail) + 1) );

            return true;
        }

        bool ErrorRepSendDialog::SendReport()
        {
            TCHAR   szTempPath[MAX_PATH];
            TCHAR   szFileName[MAX_PATH];

            GetTempPath( SAL_N_ELEMENTS(szTempPath), szTempPath );
            GetTempFileName( szTempPath, TEXT("DSC"), 0, szFileName );

            FILE *fp = _tfopen( szFileName, _T("wb") );

            if ( fp )
            {
                ByteString  strUTF8( GetUsing(), RTL_TEXTENCODING_UTF8 );

                fwrite( strUTF8.GetBuffer(), 1, strUTF8.Len(), fp );
                fclose( fp );
            }

            SetEnvironmentVariable( TEXT("ERRORREPORT_SUBJECT"), reinterpret_cast<LPCTSTR>(GetDocType().GetBuffer()) );
            SetEnvironmentVariable( TEXT("ERRORREPORT_BODYFILE"), szFileName );

            _TCHAR  szBuffer[1024];
            TCHAR   szPath[MAX_PATH];
            LPTSTR  lpFilePart;
            PROCESS_INFORMATION ProcessInfo;
            STARTUPINFO StartupInfo;

            if ( SearchPath( NULL, TEXT("crashrep.exe"), NULL, MAX_PATH, szPath, &lpFilePart ) )
            {
                ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
                StartupInfo.cb = sizeof(StartupInfo.cb);

                sntprintf( szBuffer, SAL_N_ELEMENTS(szBuffer),
                    _T("%s -noui -load -send"),
                    szPath );

                if (
                    CreateProcess(
                        NULL,
                        szBuffer,
                        NULL,
                        NULL,
                        sal_False,
                        0,
                        NULL, NULL, &StartupInfo, &ProcessInfo )
                    )
                {
                    DWORD   dwExitCode;

                    WaitForSingleObject( ProcessInfo.hProcess, INFINITE );
                    if ( GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) && 0 == dwExitCode )
                        return true;

                }
            }

            DeleteFile( szFileName );

            return false;
        }

    }   // namespace DocRecovery
}   // namespace svx

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>I meant this one<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#define UNICODE
#define _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <systools/win32/uwinapi.h>
#include <sal/macros.h>

// need to undef min and max macros from MS headers here to make
// the std::min and std::max from stl visible again
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif

#include "docrecovery.hxx"

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

static LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData )
{
    HKEY    hKey = NULL;
    LONG    lResult;

    lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );

    if ( ERROR_SUCCESS == lResult )
    {
        lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData );
        RegCloseKey( hKey );
    }

    return lResult;
}

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

static LONG RegWriteValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData )
{
    HKEY    hKey = NULL;
    LONG    lResult;

    lResult = RegCreateKeyEx( hBaseKey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );

    if ( ERROR_SUCCESS == lResult )
    {
        lResult = RegSetValueEx( hKey, lpValueName, NULL, dwType, (CONST sal_uInt8 *)lpData, cbData );
        RegCloseKey( hKey );
    }

    return lResult;
}

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

namespace svx{
    namespace DocRecovery{

        bool ErrorRepSendDialog::ReadParams()
        {
            _TCHAR  szBuffer[2048];

            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyServer"),
                szBuffer,
                sizeof(szBuffer) ) )
                maParams.maHTTPProxyServer = (sal_Unicode *)szBuffer;

            DWORD   dwProxyPort;
            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyPort"),
                &dwProxyPort,
                sizeof(dwProxyPort) ) )
            {
                _stprintf( szBuffer, _T("%d"), dwProxyPort );
                maParams.maHTTPProxyPort = (sal_Unicode *)szBuffer;
            }

            if ( ERROR_SUCCESS == RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("ReturnAddress"),
                szBuffer,
                sizeof(szBuffer) ) )
                maEMailAddrED.SetText( (sal_Unicode *)szBuffer );

            DWORD   fAllowContact = sal_False;
            RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("AllowContact"),
                &fAllowContact,
                sizeof(fAllowContact) );
            maContactCB.Check( (sal_Bool)fAllowContact );

            DWORD   uInternetConnection = 0;
            RegReadValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPConnection"),
                &uInternetConnection,
                sizeof(uInternetConnection) );
            maParams.miHTTPConnectionType = uInternetConnection;

            return true;
        }

        bool ErrorRepSendDialog::SaveParams()
        {
            const _TCHAR    *lpHTTPProxyServer = reinterpret_cast<LPCTSTR>(maParams.maHTTPProxyServer.GetBuffer());
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyServer"), REG_SZ,
                lpHTTPProxyServer,
                sizeof(TCHAR) * (_tcslen(lpHTTPProxyServer) + 1) );

            _TCHAR* endptr = NULL;
            DWORD dwProxyPort = _tcstoul( reinterpret_cast<LPCTSTR>(maParams.maHTTPProxyPort.GetBuffer()), &endptr, 10 );

            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPProxyPort"), REG_DWORD,
                &dwProxyPort,
                sizeof(DWORD) );

            DWORD   fAllowContact = IsContactAllowed();
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("AllowContact"), REG_DWORD,
                &fAllowContact,
                sizeof(DWORD) );

            DWORD uInternetConnection = maParams.miHTTPConnectionType;

            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("HTTPConnection"), REG_DWORD,
                &uInternetConnection,
                sizeof(DWORD) );

            const _TCHAR    *lpEmail = reinterpret_cast<LPCTSTR>(GetEMailAddress().GetBuffer());
            RegWriteValue(
                HKEY_CURRENT_USER,
                TEXT("SOFTWARE\\LibreOffice\\CrashReport"),
                TEXT("ReturnAddress"), REG_SZ,
                lpEmail,
                sizeof(TCHAR) * (_tcslen(lpEmail) + 1) );

            return true;
        }

        bool ErrorRepSendDialog::SendReport()
        {
            TCHAR   szTempPath[MAX_PATH];
            TCHAR   szFileName[MAX_PATH];

            GetTempPath( SAL_N_ELEMENTS(szTempPath), szTempPath );
            GetTempFileName( szTempPath, TEXT("DSC"), 0, szFileName );

            FILE *fp = _tfopen( szFileName, _T("wb") );

            if ( fp )
            {
                ByteString  strUTF8( GetUsing(), RTL_TEXTENCODING_UTF8 );

                fwrite( strUTF8.GetBuffer(), 1, strUTF8.Len(), fp );
                fclose( fp );
            }

            SetEnvironmentVariable( TEXT("ERRORREPORT_SUBJECT"), reinterpret_cast<LPCTSTR>(GetDocType().GetBuffer()) );
            SetEnvironmentVariable( TEXT("ERRORREPORT_BODYFILE"), szFileName );

            _TCHAR  szBuffer[1024];
            TCHAR   szPath[MAX_PATH];
            LPTSTR  lpFilePart;
            PROCESS_INFORMATION ProcessInfo;
            STARTUPINFO StartupInfo;

            if ( SearchPath( NULL, TEXT("crashrep.exe"), NULL, MAX_PATH, szPath, &lpFilePart ) )
            {
                ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
                StartupInfo.cb = sizeof(StartupInfo.cb);

                sntprintf( szBuffer, SAL_N_ELEMENTS(szBuffer),
                    _T("%s -noui -load -send"),
                    szPath );

                if (
                    CreateProcess(
                        NULL,
                        szBuffer,
                        NULL,
                        NULL,
                        sal_False,
                        0,
                        NULL, NULL, &StartupInfo, &ProcessInfo )
                    )
                {
                    DWORD   dwExitCode;

                    WaitForSingleObject( ProcessInfo.hProcess, INFINITE );
                    if ( GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) && 0 == dwExitCode )
                        return true;

                }
            }

            DeleteFile( szFileName );

            return false;
        }

    }   // namespace DocRecovery
}   // namespace svx

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

#include "runtime.h"

#include <cxxabi.h>
#include <execinfo.h>
#include <signal.h>
#include <string.h>

#include "logging.h"
#include "stringprintf.h"

namespace art {

static std::string Demangle(const std::string& mangled_name) {
  if (mangled_name.empty()) {
    return "??";
  }

  // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
  int status;
  char* name(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
  if (name != NULL) {
    std::string result(name);
    free(name);
    return result;
  }

  return mangled_name;
}

struct Backtrace {
  void Dump(std::ostream& os) {
    // Get the raw stack frames.
    size_t MAX_STACK_FRAMES = 128;
    void* frames[MAX_STACK_FRAMES];
    size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
    if (frame_count == 0) {
      os << "--- backtrace(3) returned no frames";
      return;
    }

    // Turn them into something human-readable with symbols.
    char** symbols = backtrace_symbols(frames, frame_count);
    if (symbols == NULL) {
      os << "--- backtrace_symbols(3) failed";
      return;
    }

    // Parse the backtrace strings and demangle, so we can produce output like this:
    // ]    #00 art::Runtime::Abort(char const*, int)+0x15b [0xf770dd51] (libartd.so)
    for (size_t i = 0; i < frame_count; ++i) {
      std::string text(symbols[i]);
      std::string filename("???");
      std::string function_name;

#if defined(__APPLE__)
      // backtrace_symbols(3) gives us lines like this on Mac OS:
      // "0   libartd.dylib                       0x001cd29a _ZN3art9Backtrace4DumpERSo + 40>"
      // "3   ???                                 0xffffffff 0x0 + 4294967295>"
      text.erase(0, 4);
      size_t index = text.find(' ');
      filename = text.substr(0, index);
      text.erase(0, 40 - 4);
      index = text.find(' ');
      std::string address(text.substr(0, index));
      text.erase(0, index + 1);
      index = text.find(' ');
      function_name = Demangle(text.substr(0, index));
      text.erase(0, index);
      text += " [" + address + "]";
#else
      // backtrace_symbols(3) gives us lines like this on Linux:
      // "/usr/local/google/home/enh/a1/out/host/linux-x86/bin/../lib/libartd.so(_ZN3art7Runtime5AbortEPKci+0x15b) [0xf76c5af3]"
      // "[0xf7b62057]"
      size_t index = text.find('(');
      if (index != std::string::npos) {
        filename = text.substr(0, index);
        text.erase(0, index + 1);

        index = text.find_first_of("+)");
        function_name = Demangle(text.substr(0, index));
        text.erase(0, index);
        index = text.find(')');
        text.erase(index, 1);
      }
#endif

      const char* last_slash = strrchr(filename.c_str(), '/');
      const char* so_name = (last_slash == NULL) ? filename.c_str() : last_slash + 1;
      os << StringPrintf("\t#%02zd ", i) << function_name << text << " (" << so_name << ")\n";
    }

    free(symbols);
  }
};

static const char* GetSignalName(int signal_number) {
  switch (signal_number) {
    case SIGABRT: return "SIGABRT";
    case SIGBUS: return "SIGBUS";
    case SIGFPE: return "SIGFPE";
    case SIGILL: return "SIGILL";
    case SIGPIPE: return "SIGPIPE";
    case SIGSEGV: return "SIGSEGV";
#if defined(STIGSTLFKT)
    case SIGSTKFLT: return "SIGSTKFLT";
#endif
    case SIGTRAP: return "SIGTRAP";
  }
  return "??";
}

static const char* GetSignalCodeName(int signal_number, int signal_code) {
  // Try the signal-specific codes...
  switch (signal_number) {
    case SIGILL:
      switch (signal_code) {
        case ILL_ILLOPC: return "ILL_ILLOPC";
        case ILL_ILLOPN: return "ILL_ILLOPN";
        case ILL_ILLADR: return "ILL_ILLADR";
        case ILL_ILLTRP: return "ILL_ILLTRP";
        case ILL_PRVOPC: return "ILL_PRVOPC";
        case ILL_PRVREG: return "ILL_PRVREG";
        case ILL_COPROC: return "ILL_COPROC";
        case ILL_BADSTK: return "ILL_BADSTK";
      }
      break;
    case SIGBUS:
      switch (signal_code) {
        case BUS_ADRALN: return "BUS_ADRALN";
        case BUS_ADRERR: return "BUS_ADRERR";
        case BUS_OBJERR: return "BUS_OBJERR";
      }
      break;
    case SIGFPE:
      switch (signal_code) {
        case FPE_INTDIV: return "FPE_INTDIV";
        case FPE_INTOVF: return "FPE_INTOVF";
        case FPE_FLTDIV: return "FPE_FLTDIV";
        case FPE_FLTOVF: return "FPE_FLTOVF";
        case FPE_FLTUND: return "FPE_FLTUND";
        case FPE_FLTRES: return "FPE_FLTRES";
        case FPE_FLTINV: return "FPE_FLTINV";
        case FPE_FLTSUB: return "FPE_FLTSUB";
      }
      break;
    case SIGSEGV:
      switch (signal_code) {
        case SEGV_MAPERR: return "SEGV_MAPERR";
        case SEGV_ACCERR: return "SEGV_ACCERR";
      }
      break;
    case SIGTRAP:
      switch (signal_code) {
        case TRAP_BRKPT: return "TRAP_BRKPT";
        case TRAP_TRACE: return "TRAP_TRACE";
      }
      break;
  }
  // Then the other codes...
  switch (signal_code) {
    case SI_USER:     return "SI_USER";
#if defined(SI_KERNEL)
    case SI_KERNEL:   return "SI_KERNEL";
#endif
    case SI_QUEUE:    return "SI_QUEUE";
    case SI_TIMER:    return "SI_TIMER";
    case SI_MESGQ:    return "SI_MESGQ";
    case SI_ASYNCIO:  return "SI_ASYNCIO";
#if defined(SI_SIGIO)
    case SI_SIGIO:    return "SI_SIGIO";
#endif
#if defined(SI_TKILL)
    case SI_TKILL:    return "SI_TKILL";
#endif
  }
  // Then give up...
  return "?";
}

struct UContext {
  UContext(void* raw_context) : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}

  void Dump(std::ostream& os) {
    // TODO: support non-x86 hosts (not urgent because this code doesn't run on targets).
#if defined(__APPLE__)
    DumpRegister32(os, "eax", context->__ss.__eax);
    DumpRegister32(os, "ebx", context->__ss.__ebx);
    DumpRegister32(os, "ecx", context->__ss.__ecx);
    DumpRegister32(os, "edx", context->__ss.__edx);
    os << '\n';

    DumpRegister32(os, "edi", context->__ss.__edi);
    DumpRegister32(os, "esi", context->__ss.__esi);
    DumpRegister32(os, "ebp", context->__ss.__ebp);
    DumpRegister32(os, "esp", context->__ss.__esp);
    os << '\n';

    DumpRegister32(os, "eip", context->__ss.__eip);
    DumpRegister32(os, "eflags", context->__ss.__eflags);
    os << '\n';

    DumpRegister32(os, "cs",  context->__ss.__cs);
    DumpRegister32(os, "ds",  context->__ss.__ds);
    DumpRegister32(os, "es",  context->__ss.__es);
    DumpRegister32(os, "fs",  context->__ss.__fs);
    os << '\n';
    DumpRegister32(os, "gs",  context->__ss.__gs);
    DumpRegister32(os, "ss",  context->__ss.__ss);
#else
    DumpRegister32(os, "eax", context.gregs[REG_EAX]);
    DumpRegister32(os, "ebx", context.gregs[REG_EBX]);
    DumpRegister32(os, "ecx", context.gregs[REG_ECX]);
    DumpRegister32(os, "edx", context.gregs[REG_EDX]);
    os << '\n';

    DumpRegister32(os, "edi", context.gregs[REG_EDI]);
    DumpRegister32(os, "esi", context.gregs[REG_ESI]);
    DumpRegister32(os, "ebp", context.gregs[REG_EBP]);
    DumpRegister32(os, "esp", context.gregs[REG_ESP]);
    os << '\n';

    DumpRegister32(os, "eip", context.gregs[REG_EIP]);
    DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
    os << '\n';

    DumpRegister32(os, "cs",  context.gregs[REG_CS]);
    DumpRegister32(os, "ds",  context.gregs[REG_DS]);
    DumpRegister32(os, "es",  context.gregs[REG_ES]);
    DumpRegister32(os, "fs",  context.gregs[REG_FS]);
    os << '\n';
    DumpRegister32(os, "gs",  context.gregs[REG_GS]);
    DumpRegister32(os, "ss",  context.gregs[REG_SS]);
#endif
  }

  void DumpRegister32(std::ostream& os, const char* name, uint32_t value) {
    os << StringPrintf(" %6s: 0x%08x", name, value);
  }

  mcontext_t& context;
};

static void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
  bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
                      signal_number == SIGFPE || signal_number == SIGSEGV);

  UContext thread_context(raw_context);
  Backtrace thread_backtrace;

  LOG(INTERNAL_FATAL) << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"
                      << StringPrintf("Fatal signal %d (%s), code %d (%s)",
                                      signal_number, GetSignalName(signal_number),
                                      info->si_code,
                                      GetSignalCodeName(signal_number, info->si_code))
                      << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << "\n"
                      << "Registers:\n" << Dumpable<UContext>(thread_context) << "\n"
                      << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace);

  // TODO: instead, get debuggerd running on the host, try to connect, and hang around on success.
  if (getenv("debug_db_uid") != NULL) {
    LOG(INTERNAL_FATAL) << "********************************************************\n"
                        << "* Process " << getpid() << " has been suspended while crashing. Attach gdb:\n"
                        << "*     gdb -p " << getpid() << "\n"
                        << "********************************************************\n";
    // Wait for debugger to attach.
    while (true) {
    }
  }
}

void Runtime::InitPlatformSignalHandlers() {
  // On the host, we don't have debuggerd to dump a stack for us when something unexpected happens.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  sigemptyset(&action.sa_mask);
  action.sa_sigaction = HandleUnexpectedSignal;
  action.sa_flags = SA_RESTART;
  // Use the three-argument sa_sigaction handler.
  action.sa_flags |= SA_SIGINFO;
  // Remove ourselves as signal handler for this signal, in case of recursion.
  action.sa_flags |= SA_RESETHAND;

  int rc = 0;
  rc += sigaction(SIGILL, &action, NULL);
  rc += sigaction(SIGTRAP, &action, NULL);
  rc += sigaction(SIGABRT, &action, NULL);
  rc += sigaction(SIGBUS, &action, NULL);
  rc += sigaction(SIGFPE, &action, NULL);
#if defined(SIGSTKFLT)
  rc += sigaction(SIGSTKFLT, &action, NULL);
#endif
  rc += sigaction(SIGPIPE, &action, NULL);

  // Use the alternate signal stack so we can catch stack overflows.
  // On Mac OS 10.7, backtrace(3) is broken and will return no frames when called from the alternate stack,
  // so we only use the alternate stack for SIGSEGV so that we at least get backtraces for other signals.
  // (glibc does the right thing, so we could use the alternate stack for all signals there.)
  action.sa_flags |= SA_ONSTACK;
  rc += sigaction(SIGSEGV, &action, NULL);

  CHECK_EQ(rc, 0);
}

}  // namespace art
<commit_msg>am 9a24dd28: Merge "Fix a SIGSTKFLT typo." into ics-mr1-plus-art<commit_after>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "runtime.h"

#include <cxxabi.h>
#include <execinfo.h>
#include <signal.h>
#include <string.h>

#include "logging.h"
#include "stringprintf.h"

namespace art {

static std::string Demangle(const std::string& mangled_name) {
  if (mangled_name.empty()) {
    return "??";
  }

  // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
  int status;
  char* name(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
  if (name != NULL) {
    std::string result(name);
    free(name);
    return result;
  }

  return mangled_name;
}

struct Backtrace {
  void Dump(std::ostream& os) {
    // Get the raw stack frames.
    size_t MAX_STACK_FRAMES = 128;
    void* frames[MAX_STACK_FRAMES];
    size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
    if (frame_count == 0) {
      os << "--- backtrace(3) returned no frames";
      return;
    }

    // Turn them into something human-readable with symbols.
    char** symbols = backtrace_symbols(frames, frame_count);
    if (symbols == NULL) {
      os << "--- backtrace_symbols(3) failed";
      return;
    }

    // Parse the backtrace strings and demangle, so we can produce output like this:
    // ]    #00 art::Runtime::Abort(char const*, int)+0x15b [0xf770dd51] (libartd.so)
    for (size_t i = 0; i < frame_count; ++i) {
      std::string text(symbols[i]);
      std::string filename("???");
      std::string function_name;

#if defined(__APPLE__)
      // backtrace_symbols(3) gives us lines like this on Mac OS:
      // "0   libartd.dylib                       0x001cd29a _ZN3art9Backtrace4DumpERSo + 40>"
      // "3   ???                                 0xffffffff 0x0 + 4294967295>"
      text.erase(0, 4);
      size_t index = text.find(' ');
      filename = text.substr(0, index);
      text.erase(0, 40 - 4);
      index = text.find(' ');
      std::string address(text.substr(0, index));
      text.erase(0, index + 1);
      index = text.find(' ');
      function_name = Demangle(text.substr(0, index));
      text.erase(0, index);
      text += " [" + address + "]";
#else
      // backtrace_symbols(3) gives us lines like this on Linux:
      // "/usr/local/google/home/enh/a1/out/host/linux-x86/bin/../lib/libartd.so(_ZN3art7Runtime5AbortEPKci+0x15b) [0xf76c5af3]"
      // "[0xf7b62057]"
      size_t index = text.find('(');
      if (index != std::string::npos) {
        filename = text.substr(0, index);
        text.erase(0, index + 1);

        index = text.find_first_of("+)");
        function_name = Demangle(text.substr(0, index));
        text.erase(0, index);
        index = text.find(')');
        text.erase(index, 1);
      }
#endif

      const char* last_slash = strrchr(filename.c_str(), '/');
      const char* so_name = (last_slash == NULL) ? filename.c_str() : last_slash + 1;
      os << StringPrintf("\t#%02zd ", i) << function_name << text << " (" << so_name << ")\n";
    }

    free(symbols);
  }
};

static const char* GetSignalName(int signal_number) {
  switch (signal_number) {
    case SIGABRT: return "SIGABRT";
    case SIGBUS: return "SIGBUS";
    case SIGFPE: return "SIGFPE";
    case SIGILL: return "SIGILL";
    case SIGPIPE: return "SIGPIPE";
    case SIGSEGV: return "SIGSEGV";
#if defined(SIGSTKFLT)
    case SIGSTKFLT: return "SIGSTKFLT";
#endif
    case SIGTRAP: return "SIGTRAP";
  }
  return "??";
}

static const char* GetSignalCodeName(int signal_number, int signal_code) {
  // Try the signal-specific codes...
  switch (signal_number) {
    case SIGILL:
      switch (signal_code) {
        case ILL_ILLOPC: return "ILL_ILLOPC";
        case ILL_ILLOPN: return "ILL_ILLOPN";
        case ILL_ILLADR: return "ILL_ILLADR";
        case ILL_ILLTRP: return "ILL_ILLTRP";
        case ILL_PRVOPC: return "ILL_PRVOPC";
        case ILL_PRVREG: return "ILL_PRVREG";
        case ILL_COPROC: return "ILL_COPROC";
        case ILL_BADSTK: return "ILL_BADSTK";
      }
      break;
    case SIGBUS:
      switch (signal_code) {
        case BUS_ADRALN: return "BUS_ADRALN";
        case BUS_ADRERR: return "BUS_ADRERR";
        case BUS_OBJERR: return "BUS_OBJERR";
      }
      break;
    case SIGFPE:
      switch (signal_code) {
        case FPE_INTDIV: return "FPE_INTDIV";
        case FPE_INTOVF: return "FPE_INTOVF";
        case FPE_FLTDIV: return "FPE_FLTDIV";
        case FPE_FLTOVF: return "FPE_FLTOVF";
        case FPE_FLTUND: return "FPE_FLTUND";
        case FPE_FLTRES: return "FPE_FLTRES";
        case FPE_FLTINV: return "FPE_FLTINV";
        case FPE_FLTSUB: return "FPE_FLTSUB";
      }
      break;
    case SIGSEGV:
      switch (signal_code) {
        case SEGV_MAPERR: return "SEGV_MAPERR";
        case SEGV_ACCERR: return "SEGV_ACCERR";
      }
      break;
    case SIGTRAP:
      switch (signal_code) {
        case TRAP_BRKPT: return "TRAP_BRKPT";
        case TRAP_TRACE: return "TRAP_TRACE";
      }
      break;
  }
  // Then the other codes...
  switch (signal_code) {
    case SI_USER:     return "SI_USER";
#if defined(SI_KERNEL)
    case SI_KERNEL:   return "SI_KERNEL";
#endif
    case SI_QUEUE:    return "SI_QUEUE";
    case SI_TIMER:    return "SI_TIMER";
    case SI_MESGQ:    return "SI_MESGQ";
    case SI_ASYNCIO:  return "SI_ASYNCIO";
#if defined(SI_SIGIO)
    case SI_SIGIO:    return "SI_SIGIO";
#endif
#if defined(SI_TKILL)
    case SI_TKILL:    return "SI_TKILL";
#endif
  }
  // Then give up...
  return "?";
}

struct UContext {
  UContext(void* raw_context) : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}

  void Dump(std::ostream& os) {
    // TODO: support non-x86 hosts (not urgent because this code doesn't run on targets).
#if defined(__APPLE__)
    DumpRegister32(os, "eax", context->__ss.__eax);
    DumpRegister32(os, "ebx", context->__ss.__ebx);
    DumpRegister32(os, "ecx", context->__ss.__ecx);
    DumpRegister32(os, "edx", context->__ss.__edx);
    os << '\n';

    DumpRegister32(os, "edi", context->__ss.__edi);
    DumpRegister32(os, "esi", context->__ss.__esi);
    DumpRegister32(os, "ebp", context->__ss.__ebp);
    DumpRegister32(os, "esp", context->__ss.__esp);
    os << '\n';

    DumpRegister32(os, "eip", context->__ss.__eip);
    DumpRegister32(os, "eflags", context->__ss.__eflags);
    os << '\n';

    DumpRegister32(os, "cs",  context->__ss.__cs);
    DumpRegister32(os, "ds",  context->__ss.__ds);
    DumpRegister32(os, "es",  context->__ss.__es);
    DumpRegister32(os, "fs",  context->__ss.__fs);
    os << '\n';
    DumpRegister32(os, "gs",  context->__ss.__gs);
    DumpRegister32(os, "ss",  context->__ss.__ss);
#else
    DumpRegister32(os, "eax", context.gregs[REG_EAX]);
    DumpRegister32(os, "ebx", context.gregs[REG_EBX]);
    DumpRegister32(os, "ecx", context.gregs[REG_ECX]);
    DumpRegister32(os, "edx", context.gregs[REG_EDX]);
    os << '\n';

    DumpRegister32(os, "edi", context.gregs[REG_EDI]);
    DumpRegister32(os, "esi", context.gregs[REG_ESI]);
    DumpRegister32(os, "ebp", context.gregs[REG_EBP]);
    DumpRegister32(os, "esp", context.gregs[REG_ESP]);
    os << '\n';

    DumpRegister32(os, "eip", context.gregs[REG_EIP]);
    DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
    os << '\n';

    DumpRegister32(os, "cs",  context.gregs[REG_CS]);
    DumpRegister32(os, "ds",  context.gregs[REG_DS]);
    DumpRegister32(os, "es",  context.gregs[REG_ES]);
    DumpRegister32(os, "fs",  context.gregs[REG_FS]);
    os << '\n';
    DumpRegister32(os, "gs",  context.gregs[REG_GS]);
    DumpRegister32(os, "ss",  context.gregs[REG_SS]);
#endif
  }

  void DumpRegister32(std::ostream& os, const char* name, uint32_t value) {
    os << StringPrintf(" %6s: 0x%08x", name, value);
  }

  mcontext_t& context;
};

static void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
  bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
                      signal_number == SIGFPE || signal_number == SIGSEGV);

  UContext thread_context(raw_context);
  Backtrace thread_backtrace;

  LOG(INTERNAL_FATAL) << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"
                      << StringPrintf("Fatal signal %d (%s), code %d (%s)",
                                      signal_number, GetSignalName(signal_number),
                                      info->si_code,
                                      GetSignalCodeName(signal_number, info->si_code))
                      << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << "\n"
                      << "Registers:\n" << Dumpable<UContext>(thread_context) << "\n"
                      << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace);

  // TODO: instead, get debuggerd running on the host, try to connect, and hang around on success.
  if (getenv("debug_db_uid") != NULL) {
    LOG(INTERNAL_FATAL) << "********************************************************\n"
                        << "* Process " << getpid() << " has been suspended while crashing. Attach gdb:\n"
                        << "*     gdb -p " << getpid() << "\n"
                        << "********************************************************\n";
    // Wait for debugger to attach.
    while (true) {
    }
  }
}

void Runtime::InitPlatformSignalHandlers() {
  // On the host, we don't have debuggerd to dump a stack for us when something unexpected happens.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  sigemptyset(&action.sa_mask);
  action.sa_sigaction = HandleUnexpectedSignal;
  action.sa_flags = SA_RESTART;
  // Use the three-argument sa_sigaction handler.
  action.sa_flags |= SA_SIGINFO;
  // Remove ourselves as signal handler for this signal, in case of recursion.
  action.sa_flags |= SA_RESETHAND;

  int rc = 0;
  rc += sigaction(SIGILL, &action, NULL);
  rc += sigaction(SIGTRAP, &action, NULL);
  rc += sigaction(SIGABRT, &action, NULL);
  rc += sigaction(SIGBUS, &action, NULL);
  rc += sigaction(SIGFPE, &action, NULL);
#if defined(SIGSTKFLT)
  rc += sigaction(SIGSTKFLT, &action, NULL);
#endif
  rc += sigaction(SIGPIPE, &action, NULL);

  // Use the alternate signal stack so we can catch stack overflows.
  // On Mac OS 10.7, backtrace(3) is broken and will return no frames when called from the alternate stack,
  // so we only use the alternate stack for SIGSEGV so that we at least get backtraces for other signals.
  // (glibc does the right thing, so we could use the alternate stack for all signals there.)
  action.sa_flags |= SA_ONSTACK;
  rc += sigaction(SIGSEGV, &action, NULL);

  CHECK_EQ(rc, 0);
}

}  // namespace art
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swfntcch.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 16:47:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#include "swfntcch.hxx"
#include "fmtcol.hxx"
#include "swfont.hxx"

// aus atrstck.cxx
extern const BYTE StackPos[];

// globale Variablen, werden in SwFntCch.Hxx bekanntgegeben
// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht
SwFontCache *pSwFontCache = NULL;

/*************************************************************************
|*
|*  SwFontObj::SwFontObj(), ~SwFontObj()
|*
|*  Ersterstellung      AMA 25. Jun. 95
|*  Letzte Aenderung    AMA 25. Jun. 95
|*
|*************************************************************************/

SwFontObj::SwFontObj( const void *pOwner, ViewShell *pSh ) :
    SwCacheObj( (void*)pOwner ),
    aSwFont( &((SwTxtFmtColl *)pOwner)->GetAttrSet(), pSh ? pSh->getIDocumentSettingAccess() : 0 )
{
    aSwFont.GoMagic( pSh, aSwFont.GetActual() );
    const SwAttrSet& rAttrSet = ((SwTxtFmtColl *)pOwner)->GetAttrSet();
    for (USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
        pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i, TRUE );
}

SwFontObj::~SwFontObj()
{
}

/*************************************************************************
|*
|*  SwFontAccess::SwFontAccess()
|*
|*  Ersterstellung      AMA 25. Jun. 95
|*  Letzte Aenderung    AMA 25. Jun. 95
|*
|*************************************************************************/

SwFontAccess::SwFontAccess( const void *pOwner, ViewShell *pSh ) :
    SwCacheAccess( *pSwFontCache, pOwner,
            (BOOL) ((SwTxtFmtColl*)pOwner)->IsInSwFntCache() ),
    pShell( pSh )
{
}

SwFontObj *SwFontAccess::Get( )
{
    return (SwFontObj *) SwCacheAccess::Get( );
}

SwCacheObj *SwFontAccess::NewObj( )
{
    ((SwTxtFmtColl*)pOwner)->SetInSwFntCache( TRUE );
    return new SwFontObj( pOwner, pShell );
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.7.2); FILE MERGED 2006/09/01 17:52:12 kaib 1.7.2.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swfntcch.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 21:46:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#include "swfntcch.hxx"
#include "fmtcol.hxx"
#include "swfont.hxx"

// aus atrstck.cxx
extern const BYTE StackPos[];

// globale Variablen, werden in SwFntCch.Hxx bekanntgegeben
// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht
SwFontCache *pSwFontCache = NULL;

/*************************************************************************
|*
|*  SwFontObj::SwFontObj(), ~SwFontObj()
|*
|*  Ersterstellung      AMA 25. Jun. 95
|*  Letzte Aenderung    AMA 25. Jun. 95
|*
|*************************************************************************/

SwFontObj::SwFontObj( const void *pOwner, ViewShell *pSh ) :
    SwCacheObj( (void*)pOwner ),
    aSwFont( &((SwTxtFmtColl *)pOwner)->GetAttrSet(), pSh ? pSh->getIDocumentSettingAccess() : 0 )
{
    aSwFont.GoMagic( pSh, aSwFont.GetActual() );
    const SwAttrSet& rAttrSet = ((SwTxtFmtColl *)pOwner)->GetAttrSet();
    for (USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
        pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i, TRUE );
}

SwFontObj::~SwFontObj()
{
}

/*************************************************************************
|*
|*  SwFontAccess::SwFontAccess()
|*
|*  Ersterstellung      AMA 25. Jun. 95
|*  Letzte Aenderung    AMA 25. Jun. 95
|*
|*************************************************************************/

SwFontAccess::SwFontAccess( const void *pOwner, ViewShell *pSh ) :
    SwCacheAccess( *pSwFontCache, pOwner,
            (BOOL) ((SwTxtFmtColl*)pOwner)->IsInSwFntCache() ),
    pShell( pSh )
{
}

SwFontObj *SwFontAccess::Get( )
{
    return (SwFontObj *) SwCacheAccess::Get( );
}

SwCacheObj *SwFontAccess::NewObj( )
{
    ((SwTxtFmtColl*)pOwner)->SetInSwFntCache( TRUE );
    return new SwFontObj( pOwner, pShell );
}

<|endoftext|>


<commit_before>#include "settingspage.hpp"
#include "ui_settingspage.h"

#include "json/assertions.h"
#include "json/value.h"
#include "json/writer.h"
#include "json/json.h"
#include "json/config.h"

#include <QDebug>

#include "util.hpp"
#include "constants.hpp"

SettingsPage::SettingsPage(QWidget *parent) :
  QWidget(parent),
  ui(new Ui::SettingsPage)
{
  ui->setupUi(this);

  ui->comboBoxDifficulty->addItem("Easy", 1);
  ui->comboBoxDifficulty->addItem("Normal", 2);
  ui->comboBoxDifficulty->addItem("Hard", 3);

  ui->comboBoxSpeed->addItem("Speed 1", 1);
  ui->comboBoxSpeed->addItem("Speed 2", 2);
  ui->comboBoxSpeed->addItem("Speed 3", 3);

  connect(this, SIGNAL(moveToMenuPage()),
          parent, SLOT(moveToMenuPage()));

  ///
  /// It reads setting data from a file.
  ///
  /// If file doesn't exits or
  /// in case it contains wrong data it won't crash the app.
  ///
  try
  {
    Json::Value settings;

    settings = Util::ReadJson(Globals::SettingsFileName);

    int currentDifficulty = settings["Difficulty"].asInt();
    int currentSpeed = settings["Speed"].asInt();

    // Set settings from the file if data is available.
    ui->comboBoxDifficulty->setCurrentIndex(currentDifficulty);
    ui->comboBoxSpeed->setCurrentIndex(currentSpeed);
  }
  catch(std::exception ex) {
    qDebug() << "Can't read settings fron a file!";
  }
}

SettingsPage::~SettingsPage()
{
  delete ui;
}

void SettingsPage::on_menuButton_clicked()
{
  emit moveToMenuPage();
}

void SettingsPage::on_saveButton_clicked()
{
  int currentDifficulty = ui->comboBoxDifficulty->currentIndex();
  int currentSpeed = ui->comboBoxSpeed->currentIndex();

  Json::Value settings;

  settings["Difficulty"] = currentDifficulty;
  settings["Speed"] = currentSpeed;

  Util::WriteJson(Globals::SettingsFileName, settings);
}
<commit_msg>fix save settings to a file<commit_after>#include "settingspage.hpp"
#include "ui_settingspage.h"

#include "json/assertions.h"
#include "json/value.h"
#include "json/writer.h"
#include "json/json.h"
#include "json/config.h"

#include <QDebug>

#include "util.hpp"
#include "constants.hpp"

SettingsPage::SettingsPage(QWidget *parent) :
  QWidget(parent),
  ui(new Ui::SettingsPage)
{
  ui->setupUi(this);

  ui->comboBoxDifficulty->addItem("Easy", 1);
  ui->comboBoxDifficulty->addItem("Normal", 2);
  ui->comboBoxDifficulty->addItem("Hard", 3);

  ui->comboBoxSpeed->addItem("Speed 1", 1);
  ui->comboBoxSpeed->addItem("Speed 2", 2);
  ui->comboBoxSpeed->addItem("Speed 3", 3);

  connect(this, SIGNAL(moveToMenuPage()),
          parent, SLOT(moveToMenuPage()));

  ///
  /// It reads setting data from a file.
  ///
  /// If file doesn't exits or
  /// in case it contains wrong data it won't crash the app.
  ///
  try
  {
    Json::Value settings;

    settings = Util::ReadJson(Globals::SettingsFileName);

    int currentDifficulty = settings["Difficulty"].asInt();
    int currentSpeed = settings["Speed"].asInt();

    // Set settings from the file if data is available.
    ui->comboBoxDifficulty->setCurrentIndex(currentDifficulty);
    ui->comboBoxSpeed->setCurrentIndex(currentSpeed);
  }
  catch(std::exception ex) {
    qDebug() << "Can't read settings fron a file!";
  }
}

SettingsPage::~SettingsPage()
{
  delete ui;
}

void SettingsPage::on_menuButton_clicked()
{
  emit moveToMenuPage();
}

void SettingsPage::on_saveButton_clicked()
{
  int currentDifficulty = ui->comboBoxDifficulty->currentIndex();
  int currentSpeed = ui->comboBoxSpeed->currentIndex();

  Json::Value settings = Util::ReadJson(Globals::SettingsFileName);

  settings["Difficulty"] = currentDifficulty;
  settings["Speed"] = currentSpeed;

  Util::WriteJson(Globals::SettingsFileName, settings);
}
<|endoftext|>


<commit_before>#include "file/path.h"

// Normalize slashes.
void PathBrowser::SetPath(const std::string &path) {
	if (path[0] == '!') {
		path_ = path;
		return;
	}
	path_ = path;
	for (size_t i = 0; i < path_.size(); i++) {
		if (path_[i] == '\\') path_[i] = '/';
	}
	if (!path_.size() || (path_[path_.size() - 1] != '/'))
		path_ += "/";
}

void PathBrowser::GetListing(std::vector<FileInfo> &fileInfo, const char *filter) {
#ifdef _WIN32
	if (path_ == "/") {
		// Special path that means root of file system.
		std::vector<std::string> drives = getWindowsDrives();
		for (auto drive = drives.begin(); drive != drives.end(); ++drive) {
			if (*drive == "A:/" || *drive == "B:/")
				continue;
			FileInfo fake;
			fake.fullName = *drive;
			fake.name = *drive;
			fake.isDirectory = true;
			fake.exists = true;
			fake.size = 0;
			fake.isWritable = false;
			fileInfo.push_back(fake);
		}
	}
#endif

	getFilesInDir(path_.c_str(), &fileInfo, filter);
}

// TODO: Support paths like "../../hello"
void PathBrowser::Navigate(const std::string &path) {
	if (path[0] == '!')
		return;

	if (path == ".")
		return;
	if (path == "..") {
		// Upwards.
		// Check for windows drives.
		if (path_.size() == 3 && path_[1] == ':') {
			path_ = "/";
		} else {
			size_t slash = path_.rfind('/', path_.size() - 2);
			if (slash != std::string::npos)
				path_ = path_.substr(0, slash + 1);
		}
	} else {
		if (path[1] == ':' && path_ == "/")
			path_ = path;
		else
			path_ = path_ + path;
		if (path_[path_.size() - 1] != '/')
			path_ += "/";
	}
}
<commit_msg>Remove unnecessary check for '!' in path browser<commit_after>#include "file/path.h"

// Normalize slashes.
void PathBrowser::SetPath(const std::string &path) {
	if (path[0] == '!') {
		path_ = path;
		return;
	}
	path_ = path;
	for (size_t i = 0; i < path_.size(); i++) {
		if (path_[i] == '\\') path_[i] = '/';
	}
	if (!path_.size() || (path_[path_.size() - 1] != '/'))
		path_ += "/";
}

void PathBrowser::GetListing(std::vector<FileInfo> &fileInfo, const char *filter) {
#ifdef _WIN32
	if (path_ == "/") {
		// Special path that means root of file system.
		std::vector<std::string> drives = getWindowsDrives();
		for (auto drive = drives.begin(); drive != drives.end(); ++drive) {
			if (*drive == "A:/" || *drive == "B:/")
				continue;
			FileInfo fake;
			fake.fullName = *drive;
			fake.name = *drive;
			fake.isDirectory = true;
			fake.exists = true;
			fake.size = 0;
			fake.isWritable = false;
			fileInfo.push_back(fake);
		}
	}
#endif

	getFilesInDir(path_.c_str(), &fileInfo, filter);
}

// TODO: Support paths like "../../hello"
void PathBrowser::Navigate(const std::string &path) {
	if (path == ".")
		return;
	if (path == "..") {
		// Upwards.
		// Check for windows drives.
		if (path_.size() == 3 && path_[1] == ':') {
			path_ = "/";
		} else {
			size_t slash = path_.rfind('/', path_.size() - 2);
			if (slash != std::string::npos)
				path_ = path_.substr(0, slash + 1);
		}
	} else {
		if (path[1] == ':' && path_ == "/")
			path_ = path;
		else
			path_ = path_ + path;
		if (path_[path_.size() - 1] != '/')
			path_ += "/";
	}
}
<|endoftext|>


<commit_before>/**
 * @file storageMapper.cc
 * @author Beata Skiba
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "storageMapper.h"
#include "veilfs.h"

#include "glog/logging.h"

#include <ctime>
#include <arpa/inet.h>

using namespace std;
using namespace boost;
using namespace veil::protocol::fuse_messages;

namespace veil {
namespace client {

StorageMapper::StorageMapper(boost::shared_ptr<FslogicProxy> fslogicProxy) :
    m_fslogic(fslogicProxy)
{
}

StorageMapper::~StorageMapper()
{
}

pair<locationInfo, storageInfo> StorageMapper::getLocationInfo(string logicalName, bool useCluster)
{
    AutoLock lock(m_fileMappingLock, READ_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it == m_fileMapping.end())
    {
        if(!useCluster)
            throw VeilException(VEIO, "cannot find file mapping in cache but using cluster is not allowed in this context");

        lock.release();
        string status = findLocation(logicalName);
        lock.lock();

        it = m_fileMapping.find(logicalName);
        if(it == m_fileMapping.end())
            throw VeilException(VEIO, "cannot find file mapping (cluster was used)");
    }

    locationInfo location = it->second;

    // Find matching storage info storage
    AutoLock sLock(m_storageMappingLock, READ_LOCK);
    map<int, storageInfo>::iterator it1 = m_storageMapping.find(location.storageId);
    if(it1 == m_storageMapping.end())
        throw VeilException(VEIO, "cannot find storage information");

    //LOG(INFO) << "found mapping for file: " << logicalName << " fileId: " << location.fileId << " storageId: " << location.storageId;
    return make_pair(it->second, it1->second);
}

string StorageMapper::findLocation(string logicalName)
{
    LOG(INFO) << "quering cluster about storage mapping for file: " << logicalName;
    FileLocation location;
    if(m_fslogic->getFileLocation(logicalName, location))
    {
        if(location.answer() == VOK)
            addLocation(logicalName, location);
        else
            LOG(WARNING) << "Cannot get storage mapping for file: " << logicalName << " due to error: " << location.answer();
        return location.answer();
    }
    else
        return VEIO;
}

void StorageMapper::addLocation(string logicalName, FileLocation location)
{
    LOG(INFO) << "adding location for file '" << logicalName << "', fileId: " << location.file_id() << " storageId: " << location.storage_id() << ", validTo: " << time(NULL) << " + " << ntohl(location.validity());

    locationInfo info;
    info.validTo = time(NULL) + location.validity();
    info.storageId = location.storage_id();
    info.fileId = location.file_id();

    storageInfo storageInfo;
    storageInfo.last_updated = time(NULL); /// @todo: last_updated field should be fetched from cluster
    if(location.has_storage_helper_name())
        storageInfo.storageHelperName = location.storage_helper_name();

    for(int i = 0; i < location.storage_helper_args_size(); ++i)
        storageInfo.storageHelperArgs.push_back(location.storage_helper_args(i));

    info.opened = 0;

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    m_fileMapping[logicalName] = info;
    AutoLock sLock(m_storageMappingLock, WRITE_LOCK);
    m_storageMapping[info.storageId] = storageInfo;

    VeilFS::getScheduler()->addTask(Job(info.validTo, shared_from_this(), TASK_REMOVE_EXPIRED_LOCATON_MAPPING, logicalName));
    VeilFS::getScheduler()->addTask(Job(info.validTo - RENEW_LOCATION_MAPPING_TIME, shared_from_this(), TASK_RENEW_LOCATION_MAPPING, logicalName));
}

void StorageMapper::openFile(string logicalName)
{
    LOG(INFO) << "marking file '" << logicalName << "' as open";

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it != m_fileMapping.end()){
         it->second.opened++;
    }
}

void StorageMapper::releaseFile(string logicalName)
{
    LOG(INFO) << "marking file '" << logicalName << "' closed";

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it != m_fileMapping.end()){
        if(it->second.opened > 0){
            it->second.opened--;
            if(it->second.opened == 0) {
                m_fileMapping.erase(logicalName);
                VeilFS::getScheduler()->addTask(Job(time(NULL), m_fslogic, ISchedulable::TASK_SEND_FILE_NOT_USED, logicalName)); // Uncomment in order to inform cluster that file isnt used anymore
            }
        }
    }
}

bool StorageMapper::runTask(TaskID taskId, string arg0, string arg1, string arg3)
{
    map<string, locationInfo>::iterator it;
    int validity;
    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    switch(taskId)
    {
        case TASK_REMOVE_EXPIRED_LOCATON_MAPPING:
            it = m_fileMapping.find(arg0);
            if(it != m_fileMapping.end() && (*it).second.validTo <= time(NULL))
            {
                LOG(INFO) << "Removing old location mapping for file: " << arg0;
                m_fileMapping.erase(arg0);
            }
            else if(it != m_fileMapping.end())
            {
                LOG(INFO) << "Recheduling old location mapping removal for file: " << arg0;
                VeilFS::getScheduler()->addTask(Job((*it).second.validTo, shared_from_this(), TASK_REMOVE_EXPIRED_LOCATON_MAPPING, arg0));
            }

            return true;
        case TASK_RENEW_LOCATION_MAPPING:
            LOG(INFO) << "Renewing file mapping for file: " << arg0;
            if((validity = m_fslogic->renewFileLocation(arg0)) <= 0)
            {
                LOG(WARNING) << "Renewing file mapping for file: " << arg0 << " failed";
                return true;
            }
            it = m_fileMapping.find(arg0);
            if(it != m_fileMapping.end())
            {
                (*it).second.validTo = time(NULL) + validity;
                LOG(INFO) << "Renewed location mapping for file: " << arg0 << ". New validity: time + " << ntohl(validity);
            }
            return true;
        case TASK_ASYNC_GET_FILE_LOCATION:
            (void) findLocation(arg0);
            return true;
        default:
            return false;
    }
}

} // namespace client
} // namespace veil
<commit_msg>VFS-292: fix file closeing<commit_after>/**
 * @file storageMapper.cc
 * @author Beata Skiba
 * @author Rafal Slota
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "storageMapper.h"
#include "veilfs.h"

#include "glog/logging.h"

#include <ctime>
#include <arpa/inet.h>

using namespace std;
using namespace boost;
using namespace veil::protocol::fuse_messages;

namespace veil {
namespace client {

StorageMapper::StorageMapper(boost::shared_ptr<FslogicProxy> fslogicProxy) :
    m_fslogic(fslogicProxy)
{
}

StorageMapper::~StorageMapper()
{
}

pair<locationInfo, storageInfo> StorageMapper::getLocationInfo(string logicalName, bool useCluster)
{
    AutoLock lock(m_fileMappingLock, READ_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it == m_fileMapping.end())
    {
        if(!useCluster)
            throw VeilException(VEIO, "cannot find file mapping in cache but using cluster is not allowed in this context");

        lock.release();
        string status = findLocation(logicalName);
        lock.lock();

        it = m_fileMapping.find(logicalName);
        if(it == m_fileMapping.end())
            throw VeilException(VEIO, "cannot find file mapping (cluster was used)");
    }

    locationInfo location = it->second;

    // Find matching storage info storage
    AutoLock sLock(m_storageMappingLock, READ_LOCK);
    map<int, storageInfo>::iterator it1 = m_storageMapping.find(location.storageId);
    if(it1 == m_storageMapping.end())
        throw VeilException(VEIO, "cannot find storage information");

    //LOG(INFO) << "found mapping for file: " << logicalName << " fileId: " << location.fileId << " storageId: " << location.storageId;
    return make_pair(it->second, it1->second);
}

string StorageMapper::findLocation(string logicalName)
{
    LOG(INFO) << "quering cluster about storage mapping for file: " << logicalName;
    FileLocation location;
    if(m_fslogic->getFileLocation(logicalName, location))
    {
        if(location.answer() == VOK)
            addLocation(logicalName, location);
        else
            LOG(WARNING) << "Cannot get storage mapping for file: " << logicalName << " due to error: " << location.answer();
        return location.answer();
    }
    else
        return VEIO;
}

void StorageMapper::addLocation(string logicalName, FileLocation location)
{
    LOG(INFO) << "adding location for file '" << logicalName << "', fileId: " << location.file_id() << " storageId: " << location.storage_id() << ", validTo: " << time(NULL) << " + " << ntohl(location.validity());

    locationInfo info;
    info.validTo = time(NULL) + location.validity();
    info.storageId = location.storage_id();
    info.fileId = location.file_id();

    storageInfo storageInfo;
    storageInfo.last_updated = time(NULL); /// @todo: last_updated field should be fetched from cluster
    if(location.has_storage_helper_name())
        storageInfo.storageHelperName = location.storage_helper_name();

    for(int i = 0; i < location.storage_helper_args_size(); ++i)
        storageInfo.storageHelperArgs.push_back(location.storage_helper_args(i));

    info.opened = 0;

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    m_fileMapping[logicalName] = info;
    AutoLock sLock(m_storageMappingLock, WRITE_LOCK);
    m_storageMapping[info.storageId] = storageInfo;

    VeilFS::getScheduler()->addTask(Job(info.validTo, shared_from_this(), TASK_REMOVE_EXPIRED_LOCATON_MAPPING, logicalName));
    VeilFS::getScheduler()->addTask(Job(info.validTo - RENEW_LOCATION_MAPPING_TIME, shared_from_this(), TASK_RENEW_LOCATION_MAPPING, logicalName));
}

void StorageMapper::openFile(string logicalName)
{
    LOG(INFO) << "marking file '" << logicalName << "' as open";

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it != m_fileMapping.end()){
         it->second.opened++;
    }
}

void StorageMapper::releaseFile(string logicalName)
{
    LOG(INFO) << "marking file '" << logicalName << "' closed";

    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it != m_fileMapping.end()){
        if(it->second.opened > 0){
            it->second.opened--;
            if(it->second.opened == 0) {
                m_fileMapping.erase(logicalName);
                m_fslogic->sendFileNotUsed(logicalName);
            }
        }
    }
}

bool StorageMapper::runTask(TaskID taskId, string arg0, string arg1, string arg3)
{
    map<string, locationInfo>::iterator it;
    int validity;
    AutoLock lock(m_fileMappingLock, WRITE_LOCK);
    switch(taskId)
    {
        case TASK_REMOVE_EXPIRED_LOCATON_MAPPING:
            it = m_fileMapping.find(arg0);
            if(it != m_fileMapping.end() && (*it).second.validTo <= time(NULL))
            {
                LOG(INFO) << "Removing old location mapping for file: " << arg0;
                m_fileMapping.erase(arg0);
            }
            else if(it != m_fileMapping.end())
            {
                LOG(INFO) << "Recheduling old location mapping removal for file: " << arg0;
                VeilFS::getScheduler()->addTask(Job((*it).second.validTo, shared_from_this(), TASK_REMOVE_EXPIRED_LOCATON_MAPPING, arg0));
            }

            return true;
        case TASK_RENEW_LOCATION_MAPPING:
            LOG(INFO) << "Renewing file mapping for file: " << arg0;
            if((validity = m_fslogic->renewFileLocation(arg0)) <= 0)
            {
                LOG(WARNING) << "Renewing file mapping for file: " << arg0 << " failed";
                return true;
            }
            it = m_fileMapping.find(arg0);
            if(it != m_fileMapping.end())
            {
                (*it).second.validTo = time(NULL) + validity;
                LOG(INFO) << "Renewed location mapping for file: " << arg0 << ". New validity: time + " << ntohl(validity);
            }
            return true;
        case TASK_ASYNC_GET_FILE_LOCATION:
            (void) findLocation(arg0);
            return true;
        default:
            return false;
    }
}

} // namespace client
} // namespace veil
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> // for exit()
#include "setup_transfer.hpp" // for tests_failure
#include "dht_server.hpp" // for stop_dht
#include "peer_server.hpp" // for stop_peer

int test_main();

#include "libtorrent/assert.hpp"
#include "libtorrent/file.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];

#if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || TORRENT_RELEASE_ASSERTS
	print_backtrace(stack_text, sizeof(stack_text), 30);
#elif defined __FUNCTION__
	strcat(stack_text, __FUNCTION__);
#else
	stack_text[0] = 0;
#endif
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
#ifdef SIGBUS
		SIG(SIGBUS);
#endif
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
#ifdef SIGSYS
		SIG(SIGSYS);
#endif
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

using namespace libtorrent;

int main()
{
	srand(total_microseconds(time_now_hires() - min_time()));
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
#ifdef SIGBUS
	signal(SIGBUS, &sig_handler);
#endif
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
#ifdef SIGSYS
	signal(SIGSYS, &sig_handler);
#endif

	char dir[40];
	snprintf(dir, sizeof(dir), "test_tmp_%u", rand());
	std::string test_dir = complete(dir);
	error_code ec;
	create_directory(test_dir, ec);
	if (ec)
	{
		fprintf(stderr, "Failed to create test directory: %s\n", ec.message().c_str());
		return 1;
	}
#ifdef TORRENT_WINDOWS
	SetCurrentDirectoryA(dir);
#else
	chdir(dir);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif

	// just in case of premature exits
	// make sure we try to clean up some
	stop_tracker();
	stop_all_proxies();
	stop_web_server();
	stop_peer();
	stop_dht();

	fflush(stdout);
	fflush(stderr);
	remove_all(test_dir, ec);
	if (ec)
		fprintf(stderr, "failed to remove test dir: %s\n", ec.message().c_str());
	return tests_failure ? 1 : 0;
}

<commit_msg>SetErrorMode at the start of unit tests (on windows)<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> // for exit()
#include "setup_transfer.hpp" // for tests_failure
#include "dht_server.hpp" // for stop_dht
#include "peer_server.hpp" // for stop_peer

int test_main();

#include "libtorrent/assert.hpp"
#include "libtorrent/file.hpp"
#include <signal.h>

#ifdef WIN32
#include <windows.h> // fot SetErrorMode
#endif

void sig_handler(int sig)
{
	char stack_text[10000];

#if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || TORRENT_RELEASE_ASSERTS
	print_backtrace(stack_text, sizeof(stack_text), 30);
#elif defined __FUNCTION__
	strcat(stack_text, __FUNCTION__);
#else
	stack_text[0] = 0;
#endif
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
#ifdef SIGBUS
		SIG(SIGBUS);
#endif
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
#ifdef SIGSYS
		SIG(SIGSYS);
#endif
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

using namespace libtorrent;

int main()
{
#ifdef WIN32
	// try to suppress hanging the process by windows displaying
	// modal dialogs.
	SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOALIGNMENTFAULTEXCEPT
		| SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
#endif

	srand(total_microseconds(time_now_hires() - min_time()));
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
#ifdef SIGBUS
	signal(SIGBUS, &sig_handler);
#endif
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
#ifdef SIGSYS
	signal(SIGSYS, &sig_handler);
#endif

	char dir[40];
	snprintf(dir, sizeof(dir), "test_tmp_%u", rand());
	std::string test_dir = complete(dir);
	error_code ec;
	create_directory(test_dir, ec);
	if (ec)
	{
		fprintf(stderr, "Failed to create test directory: %s\n", ec.message().c_str());
		return 1;
	}
#ifdef TORRENT_WINDOWS
	SetCurrentDirectoryA(dir);
#else
	chdir(dir);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif

	// just in case of premature exits
	// make sure we try to clean up some
	stop_tracker();
	stop_all_proxies();
	stop_web_server();
	stop_peer();
	stop_dht();

	fflush(stdout);
	fflush(stderr);
	remove_all(test_dir, ec);
	if (ec)
		fprintf(stderr, "failed to remove test dir: %s\n", ec.message().c_str());
	return tests_failure ? 1 : 0;
}

<|endoftext|>