<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2002,2014              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
  @file prdfHomRegisterAccess.C
  @brief definition of HomRegisterAccess
*/
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define prdfHomRegisterAccess_C

#ifdef __HOSTBOOT_MODULE
  #include <ecmdDataBufferBase.H>
  #include <ibscomreasoncodes.H>
#else
  #include <ecmdDataBuffer.H>
  #include <hwsvExecutionService.H>
  #include <hwco_service_codes.H>
#endif

#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
#include <iipbits.h>
#include <prdfMain.H>
#include <prdfPlatServices.H>
#include <prdfGlobal.H>
#include <prdfErrlUtil.H>
#include <prdfTrace.H>

#undef prdfHomRegisterAccess_C

namespace PRDF
{

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//------------------------------------------------------------------------------
// Member Function Specifications
//------------------------------------------------------------------------------

ScomService& getScomService()
{
    return PRDF_GET_SINGLETON(theScomService);
}

ScomService::ScomService() :
    iv_ScomAccessor(NULL)
{
    PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
    iv_ScomAccessor = new ScomAccessor();
}

ScomService::~ScomService()
{
    if(NULL != iv_ScomAccessor)
    {
        PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }
}

void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
{
    PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");

    if(NULL != iv_ScomAccessor)
    {
        PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }

    iv_ScomAccessor = &i_ScomAccessor;
}

uint32_t ScomService::Access(TARGETING::TargetHandle_t i_target,
                                 BIT_STRING_CLASS & bs,
                                 uint64_t registerId,
                                 MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomService::Access()");
    int32_t rc = SUCCESS;

    errlHndl_t errlH = iv_ScomAccessor->Access( i_target,
                                          bs,
                                          registerId,
                                          operation);
    #ifdef __HOSTBOOT_MODULE
    if( ( NULL != errlH ) && ( MopRegisterAccess::READ == operation )
        && ( IBSCOM::IBSCOM_BUS_FAILURE == errlH->reasonCode() ))
    {
        PRDF_COMMIT_ERRL(errlH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        PRDF_INF( "Register access failed with reason code IBSCOM_BUS_FAILURE."
                  " Trying again, Target HUID:0x%08X Register 0x%016X Op:%u",
                  PlatServices::getHuid( i_target), registerId, operation );

        errlH = iv_ScomAccessor->Access( i_target,
                                         bs,
                                         registerId,
                                         operation);
    }
    #endif

    #ifndef __HOSTBOOT_MODULE
    if (errlH != NULL && HWCO_SLW_IN_CHECKSTOP == errlH->getRC())
    {
        // We can get a flood of errors from a core in sleep/winkle at the
        // time of a checkstop. An errorlog will already be committed for
        // for this, so we will ignore these errors here.
        delete errlH;
        errlH = NULL;
        rc = PRD_SCANCOM_FAILURE;
        bs.Clear();
    }
    #endif

    if(errlH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errlH, rc, PRDF_HOM_SCOM, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errlH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errlH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        }
        else
        {
            delete errlH;
            errlH = NULL;
        }
    }

    PRDF_DEXIT("ScomService::Access(): rc=%d", rc);

    return rc;
}

errlHndl_t ScomAccessor::Access(TARGETING::TargetHandle_t i_target,
                                  BIT_STRING_CLASS & bs,
                                  uint64_t registerId,
                                  MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomAccessor::Access()");

    errlHndl_t errH = NULL;
    uint32_t bsize = bs.GetLength();

    if(i_target != NULL)
    {
        #ifdef __HOSTBOOT_MODULE

        ecmdDataBufferBase buffer(bsize);

        #else

        ecmdDataBuffer buffer(bsize);

        #endif

        switch (operation)
        {
            case MopRegisterAccess::WRITE:
                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(bs.IsSet(i)) buffer.setBit(i);
                }

                // FIXME: If register is in a EX chiplet, need to also update
                //        PORE image ????

                PRD_FAPI_TO_ERRL(errH,
                                 fapiPutScom,
                                 PlatServices::getFapiTarget(i_target),
                                 registerId,
                                 buffer);

                break;

            case MopRegisterAccess::READ:
                bs.Pattern(0x00000000); // clear all bits

                PRD_FAPI_TO_ERRL(errH,
                                 fapiGetScom,
                                 PlatServices::getFapiTarget(i_target),
                                 registerId,
                                 buffer);

                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(buffer.isBitSet(i)) bs.Set(i);
                }

                break;

            default:
                PRDF_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X", operation);
                break;

        } // end switch operation

    }
    else // Invalid target
    {
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_CODE_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The invalid ID causing the fail
         * @devdesc    Access SCOM failed due to NULL target handle
         * @custDesc   An internal firmware fault, access failed on hardware
         *             register.
         * @procedure  EPUB_PRC_SP_CODE
         */

        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,        // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,              // module id
                         FSP_DEFAULT_REFCODE,        // refcode What do we use???
                         PRDF_CODE_FAIL,             // Reason code
                         SCR_ACCESS_FAILED,          // user data word 1
                         PlatServices::getHuid(i_target),   // user data word 2
                         0x0000,                     // user data word 3
                         0x0000                      // user data word 4
                         );
    }

    PRDF_DEXIT("ScomAccessor::Access()");

    return errH;
}

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

uint32_t HomRegisterAccessScom::Access( BIT_STRING_CLASS & bs,
                                        uint64_t registerId,
                                        Operation operation) const
{
    PRDF_DENTER("HomRegisterAccessScom::Access()");

    uint32_t rc = getScomService().Access(iv_ptargetHandle,
                                           bs,
                                           registerId,
                                           operation);

    PRDF_DEXIT("HomRegisterAccessScom::Access() rc=%d", rc);

    return rc;
}

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

HomRegisterAccessScan::HomRegisterAccessScan(
                                    TARGETING::TargetHandle_t i_ptargetHandle,
                                    ScanRingField * start, ScanRingField * end )
: MopRegisterAccess(), iv_punitHandle(i_ptargetHandle)
{
    iv_aliasIds.reserve(end-start);
    while(start != end)
    {
        iv_aliasIds.push_back(*start);
        ++start;
    }
}

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

uint32_t HomRegisterAccessScan::Access(BIT_STRING_CLASS & bs,
                                   uint64_t registerId,
                                   Operation operation) const
{

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    HUID l_chipHUID = PlatServices::getHuid(iv_punitHandle);
    if(operation == MopRegisterAccess::READ)
    {
        if(iv_punitHandle != NULL)
        {
            #ifdef __HOSTBOOT_MODULE
            ecmdDataBufferBase buf(bs.GetLength());
            #else
            ecmdDataBuffer buf(bs.GetLength());
            #endif

            uint32_t curbit = 0;
            bs.Pattern(0x00000000); // clear desination bit string
            for(AliasIdList::const_iterator i = iv_aliasIds.begin(); i != iv_aliasIds.end(); ++i)
            {
                for(uint32_t j = 0; j != i->length; ++j)
                {
                    if(buf.isBitSet(j)) bs.Set(j+curbit);
                }
                curbit += i->length;
            }
        }
        else
        {

            /*@
             * @errortype
             * @subsys     EPUB_FIRMWARE_SP
             * @reasoncode PRDF_CODE_FAIL
             * @moduleid   PRDF_HOM_SCAN
             * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
             * @userdata2  The invalid ID causing the fail
             * @userdata3  Code location = 0x0001
             * @devdesc    Access Scan failed due to an invalid function unit
             * @custDesc   An internal firmware fault, read failed on hardware
             *             register.
             * @procedure EPUB_PRC_SP_CODE
             */
            // create an error log
            PRDF_CREATE_ERRL(errH,
                             ERRL_SEV_PREDICTIVE,       // error on diagnostic
                             ERRL_ETYPE_NOT_APPLICABLE,
                             SRCI_MACH_CHECK,
                             SRCI_NO_ATTR,
                             PRDF_HOM_SCAN,             // module id
                             FSP_DEFAULT_REFCODE,       // refcode What do we use???
                             PRDF_CODE_FAIL,            // Reason code
                             SCR_ACCESS_FAILED,         // user data word 1
                             l_chipHUID,                // user data word 2
                             0x0001,                    // user data word 3
                             0x0000                     // user data word 4
                             );
        }
    }
    // PRD does not ever expect to write scan rings - create an error log
    else
    {
        PRDF_ERR( "HomRegisterAccessScan::Access "
                  "only scan read is supported.  Invalid Scan Op: 0x%.8X", operation );

        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_UNSUPPORTED_SCAN_WRITE
         * @moduleid   PRDF_HOM_SCAN
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The ID for the scan
         * @userdata3  Code location = 0x0002
         * @devdesc    Access Scan failed. PRD does not ever expect to write scan rings.
         * @custDesc   An internal firmware fault, write failed on hardware
         *             register.
         * @procedure EPUB_PRC_SP_CODE
         */
        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,       // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCAN,             // module id
                         FSP_DEFAULT_REFCODE,       // refcode What do we use???
                         PRDF_UNSUPPORTED_SCAN_WRITE, // Reason code
                         SCR_ACCESS_FAILED,         // user data word 1
                         l_chipHUID,                // user data word 2
                         0x0002,                    // user data word 3
                         0x0000                     // user data word 4
                         );
    }
    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCAN, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);

        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }

    return rc;
}

} // End namespace PRDF
<commit_msg>PRD: Add scom to SLW image to mask EX FIRs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2002,2014              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
  @file prdfHomRegisterAccess.C
  @brief definition of HomRegisterAccess
*/
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define prdfHomRegisterAccess_C

#ifdef __HOSTBOOT_MODULE
  #include <ecmdDataBufferBase.H>
  #include <ibscomreasoncodes.H>
#else
  #include <ecmdDataBuffer.H>
  #include <hwsvExecutionService.H>
  #include <hwco_service_codes.H>
  #include <p8_pore_table_gen_api.H>
#endif

#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
#include <iipbits.h>
#include <prdfMain.H>
#include <prdfPlatServices.H>
#include <prdfGlobal.H>
#include <prdfErrlUtil.H>
#include <prdfTrace.H>

#undef prdfHomRegisterAccess_C

using namespace TARGETING;

namespace PRDF
{

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//------------------------------------------------------------------------------
// Member Function Specifications
//------------------------------------------------------------------------------

ScomService& getScomService()
{
    return PRDF_GET_SINGLETON(theScomService);
}

ScomService::ScomService() :
    iv_ScomAccessor(NULL)
{
    PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
    iv_ScomAccessor = new ScomAccessor();
}

ScomService::~ScomService()
{
    if(NULL != iv_ScomAccessor)
    {
        PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }
}

void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
{
    PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");

    if(NULL != iv_ScomAccessor)
    {
        PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }

    iv_ScomAccessor = &i_ScomAccessor;
}

uint32_t ScomService::Access(TargetHandle_t i_target,
                             BIT_STRING_CLASS & bs,
                             uint64_t registerId,
                             MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomService::Access()");
    int32_t rc = SUCCESS;

    errlHndl_t errlH = iv_ScomAccessor->Access( i_target,
                                          bs,
                                          registerId,
                                          operation);
    #ifdef __HOSTBOOT_MODULE
    if( ( NULL != errlH ) && ( MopRegisterAccess::READ == operation )
        && ( IBSCOM::IBSCOM_BUS_FAILURE == errlH->reasonCode() ))
    {
        PRDF_COMMIT_ERRL(errlH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        PRDF_INF( "Register access failed with reason code IBSCOM_BUS_FAILURE."
                  " Trying again, Target HUID:0x%08X Register 0x%016X Op:%u",
                  PlatServices::getHuid( i_target), registerId, operation );

        errlH = iv_ScomAccessor->Access( i_target,
                                         bs,
                                         registerId,
                                         operation);
    }
    #endif

    #ifndef __HOSTBOOT_MODULE
    if (errlH != NULL && HWCO_SLW_IN_CHECKSTOP == errlH->getRC())
    {
        // We can get a flood of errors from a core in sleep/winkle at the
        // time of a checkstop. An errorlog will already be committed for
        // for this, so we will ignore these errors here.
        delete errlH;
        errlH = NULL;
        rc = PRD_SCANCOM_FAILURE;
        bs.Clear();
    }
    #endif

    if(errlH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errlH, rc, PRDF_HOM_SCOM, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errlH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errlH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        }
        else
        {
            delete errlH;
            errlH = NULL;
        }
    }

    PRDF_DEXIT("ScomService::Access(): rc=%d", rc);

    return rc;
}

errlHndl_t ScomAccessor::Access(TargetHandle_t i_target,
                                BIT_STRING_CLASS & bs,
                                uint64_t registerId,
                                MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomAccessor::Access()");

    errlHndl_t errH = NULL;
    uint32_t bsize = bs.GetLength();

    if(i_target != NULL)
    {
        #ifdef __HOSTBOOT_MODULE

        ecmdDataBufferBase buffer(bsize);

        #else

        ecmdDataBuffer buffer(bsize);

        #endif

        switch (operation)
        {
            case MopRegisterAccess::WRITE:
            {
                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(bs.IsSet(i)) buffer.setBit(i);
                }

                PRD_FAPI_TO_ERRL(errH,
                                 fapiPutScom,
                                 PlatServices::getFapiTarget(i_target),
                                 registerId,
                                 buffer);

                #ifndef __HOSTBOOT_MODULE

                if( NULL != errH ) break;

                // If register is in a EX chiplet, need to update PORE image.
                // The PORE update is necessary to avoid loosing the FIR MASK
                // after the Core exits the sleep-winkle state.
                if( TYPE_EX == PlatServices::getTargetType(i_target) )
                {
                    // In SLW image we only have space for 32 registers and
                    // that space is not exclusive to PRD.
                    // Though we can write to Mask directly or using AND
                    // register but when we mask a FIR bit for Predictive
                    // callout, we always use OR register.
                    // So we will only consider OR register here as it will
                    // simplify our logic and  will also help to meet SLW
                    // image size requirement.
                    // Using OR register only also enables us to use SCOM_OR
                    // operation in underlying platform API which further
                    // helps to reduce size of SLW Image.
                    uint32_t l_exMaskReg[5] = {
                                        0x1004000f,   // EX_LOCAL_FIR_MASK_OR
                                        0x10013105,   // EX_CORE_FIR_MASK_OR
                                        0x10012805,   // EX_L2CERRS_FIR_MASK_OR
                                        0x10010805,   // EX_L3CERRS_FIR_MASK_OR
                                        0x10010c05 }; // EX_NCSCOMS_FIR_MASK_OR

                    for(uint32_t l_count = 0; l_count < 5; l_count++)
                    {
                        if( l_exMaskReg[l_count]  == registerId )
                        {
                            int32_t l_rc = SUCCESS;
                            l_rc = PlatServices::updateExScomToSlwImage(
                                                              i_target,
                                                              registerId,
                                                              buffer,
                                                              P8_PORE_SCOM_OR );
                            if( SUCCESS != l_rc )
                            {
                                PRDF_ERR("[ScomAccessor::Access()] Error in"
                                         " updateExScomToSlwImage.");
                            }
                            break;
                        }
                    }
                }
                #endif // End of, not __HOSTBOOT_MODULE

                break;
            }

            case MopRegisterAccess::READ:
                bs.Pattern(0x00000000); // clear all bits

                PRD_FAPI_TO_ERRL(errH,
                                 fapiGetScom,
                                 PlatServices::getFapiTarget(i_target),
                                 registerId,
                                 buffer);

                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(buffer.isBitSet(i)) bs.Set(i);
                }

                break;

            default:
                PRDF_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X",
                          operation);
                break;

        } // end switch operation

    }
    else // Invalid target
    {
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_CODE_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The invalid ID causing the fail
         * @devdesc    Access SCOM failed due to NULL target handle
         * @custDesc   An internal firmware fault, access failed on hardware
         *             register.
         * @procedure  EPUB_PRC_SP_CODE
         */

        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,        // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,              // module id
                         FSP_DEFAULT_REFCODE,        // refcode What do we use??
                         PRDF_CODE_FAIL,             // Reason code
                         SCR_ACCESS_FAILED,          // user data word 1
                         PlatServices::getHuid(i_target),   // user data word 2
                         0x0000,                     // user data word 3
                         0x0000                      // user data word 4
                         );
    }

    PRDF_DEXIT("ScomAccessor::Access()");

    return errH;
}

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

uint32_t HomRegisterAccessScom::Access( BIT_STRING_CLASS & bs,
                                        uint64_t registerId,
                                        Operation operation) const
{
    PRDF_DENTER("HomRegisterAccessScom::Access()");

    uint32_t rc = getScomService().Access(iv_ptargetHandle,
                                           bs,
                                           registerId,
                                           operation);

    PRDF_DEXIT("HomRegisterAccessScom::Access() rc=%d", rc);

    return rc;
}

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

HomRegisterAccessScan::HomRegisterAccessScan(
                                    TargetHandle_t i_ptargetHandle,
                                    ScanRingField * start, ScanRingField * end )
: MopRegisterAccess(), iv_punitHandle(i_ptargetHandle)
{
    iv_aliasIds.reserve(end-start);
    while(start != end)
    {
        iv_aliasIds.push_back(*start);
        ++start;
    }
}

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

uint32_t HomRegisterAccessScan::Access(BIT_STRING_CLASS & bs,
                                   uint64_t registerId,
                                   Operation operation) const
{

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    HUID l_chipHUID = PlatServices::getHuid(iv_punitHandle);
    if(operation == MopRegisterAccess::READ)
    {
        if(iv_punitHandle != NULL)
        {
            #ifdef __HOSTBOOT_MODULE
            ecmdDataBufferBase buf(bs.GetLength());
            #else
            ecmdDataBuffer buf(bs.GetLength());
            #endif

            uint32_t curbit = 0;
            bs.Pattern(0x00000000); // clear desination bit string
            for(AliasIdList::const_iterator i = iv_aliasIds.begin(); i != iv_aliasIds.end(); ++i)
            {
                for(uint32_t j = 0; j != i->length; ++j)
                {
                    if(buf.isBitSet(j)) bs.Set(j+curbit);
                }
                curbit += i->length;
            }
        }
        else
        {

            /*@
             * @errortype
             * @subsys     EPUB_FIRMWARE_SP
             * @reasoncode PRDF_CODE_FAIL
             * @moduleid   PRDF_HOM_SCAN
             * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
             * @userdata2  The invalid ID causing the fail
             * @userdata3  Code location = 0x0001
             * @devdesc    Access Scan failed due to an invalid function unit
             * @custDesc   An internal firmware fault, read failed on hardware
             *             register.
             * @procedure EPUB_PRC_SP_CODE
             */
            // create an error log
            PRDF_CREATE_ERRL(errH,
                             ERRL_SEV_PREDICTIVE,       // error on diagnostic
                             ERRL_ETYPE_NOT_APPLICABLE,
                             SRCI_MACH_CHECK,
                             SRCI_NO_ATTR,
                             PRDF_HOM_SCAN,             // module id
                             FSP_DEFAULT_REFCODE,       // refcode What do we use???
                             PRDF_CODE_FAIL,            // Reason code
                             SCR_ACCESS_FAILED,         // user data word 1
                             l_chipHUID,                // user data word 2
                             0x0001,                    // user data word 3
                             0x0000                     // user data word 4
                             );
        }
    }
    // PRD does not ever expect to write scan rings - create an error log
    else
    {
        PRDF_ERR( "HomRegisterAccessScan::Access "
                  "only scan read is supported.  Invalid Scan Op: 0x%.8X", operation );

        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_UNSUPPORTED_SCAN_WRITE
         * @moduleid   PRDF_HOM_SCAN
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The ID for the scan
         * @userdata3  Code location = 0x0002
         * @devdesc    Access Scan failed. PRD does not ever expect to write scan rings.
         * @custDesc   An internal firmware fault, write failed on hardware
         *             register.
         * @procedure EPUB_PRC_SP_CODE
         */
        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,       // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCAN,             // module id
                         FSP_DEFAULT_REFCODE,       // refcode What do we use???
                         PRDF_UNSUPPORTED_SCAN_WRITE, // Reason code
                         SCR_ACCESS_FAILED,         // user data word 1
                         l_chipHUID,                // user data word 2
                         0x0002,                    // user data word 3
                         0x0000                     // user data word 4
                         );
    }
    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCAN, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);

        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }

    return rc;
}

} // End namespace PRDF
<|endoftext|>


<commit_before>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/c/c_api.h"

#include <memory>

#include "tensorflow/lite/builtin_ops.h"
#include "tensorflow/lite/c/c_api_internal.h"
#include "tensorflow/lite/delegates/interpreter_utils.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate.h"
#include "tensorflow/lite/error_reporter.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/internal/compatibility.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/version.h"

namespace {
class CallbackErrorReporter : public tflite::ErrorReporter {
 public:
  explicit CallbackErrorReporter(TfLiteErrorReporterCallback callback)
      : callback_(callback) {}

  int Report(const char* format, va_list args) override {
    callback_.error_reporter(callback_.user_data, format, args);
    return 0;
  }

 private:
  TfLiteErrorReporterCallback callback_;
};

/// `CallbackOpResolver` is a (C++) `tflite::OpResolver` that forwards the
/// methods to (C ABI) callback functions from a `TfLiteOpResolverCallbacks`
/// struct.
///
/// The SetCallbacks method must be called before calling any of the FindOp
/// methods.
class CallbackOpResolver : public ::tflite::OpResolver {
 public:
  CallbackOpResolver() {}
  void SetCallbacks(
      const struct TfLiteOpResolverCallbacks& op_resolver_callbacks) {
    op_resolver_callbacks_ = op_resolver_callbacks;
  }
  const TfLiteRegistration* FindOp(tflite::BuiltinOperator op,
                                   int version) const override {
    if (op_resolver_callbacks_.find_builtin_op == nullptr) {
      return nullptr;
    }
    return op_resolver_callbacks_.find_builtin_op(
        op_resolver_callbacks_.user_data,
        static_cast<TfLiteBuiltinOperator>(op), version);
  }
  const TfLiteRegistration* FindOp(const char* op, int version) const override {
    if (op_resolver_callbacks_.find_custom_op == nullptr) {
      return nullptr;
    }
    return op_resolver_callbacks_.find_custom_op(
        op_resolver_callbacks_.user_data, op, version);
  }

 private:
  CallbackOpResolver(const CallbackOpResolver&) = delete;
  CallbackOpResolver& operator=(const CallbackOpResolver&) = delete;

  struct TfLiteOpResolverCallbacks op_resolver_callbacks_ = {};
};

}  // namespace

extern "C" {

// LINT.IfChange

const char* TfLiteVersion() { return TFLITE_VERSION_STRING; }

TfLiteModel* TfLiteModelCreate(const void* model_data, size_t model_size) {
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(
      static_cast<const char*>(model_data), model_size);
  std::shared_ptr<const tflite::FlatBufferModel> shared_model(model.release());
  return shared_model ? new TfLiteModel{std::move(shared_model)} : nullptr;
}

TfLiteModel* TfLiteModelCreateFromFile(const char* model_path) {
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromFile(model_path);
  std::shared_ptr<const tflite::FlatBufferModel> shared_model(model.release());
  return shared_model ? new TfLiteModel{std::move(shared_model)} : nullptr;
}

void TfLiteModelDelete(TfLiteModel* model) { delete model; }

TfLiteInterpreterOptions* TfLiteInterpreterOptionsCreate() {
  return new TfLiteInterpreterOptions{};
}

void TfLiteInterpreterOptionsDelete(TfLiteInterpreterOptions* options) {
  delete options;
}

void TfLiteInterpreterOptionsSetNumThreads(TfLiteInterpreterOptions* options,
                                           int32_t num_threads) {
  options->num_threads = num_threads;
}

void TfLiteInterpreterOptionsAddDelegate(TfLiteInterpreterOptions* options,
                                         TfLiteDelegate* delegate) {
  options->delegates.push_back(delegate);
}

void TfLiteInterpreterOptionsSetErrorReporter(
    TfLiteInterpreterOptions* options,
    void (*reporter)(void* user_data, const char* format, va_list args),
    void* user_data) {
  options->error_reporter_callback.error_reporter = reporter;
  options->error_reporter_callback.user_data = user_data;
}

TfLiteInterpreter* TfLiteInterpreterCreate(
    const TfLiteModel* model,
    const TfLiteInterpreterOptions* optional_options) {
  tflite::ops::builtin::BuiltinOpResolver resolver;
  return tflite::internal::InterpreterCreateWithOpResolver(
      model, optional_options, &resolver);
}

void TfLiteInterpreterDelete(TfLiteInterpreter* interpreter) {
  delete interpreter;
}

int32_t TfLiteInterpreterGetInputTensorCount(
    const TfLiteInterpreter* interpreter) {
  return static_cast<int32_t>(interpreter->impl->inputs().size());
}

TfLiteTensor* TfLiteInterpreterGetInputTensor(
    const TfLiteInterpreter* interpreter, int32_t input_index) {
  return interpreter->impl->tensor(interpreter->impl->inputs()[input_index]);
}

TfLiteStatus TfLiteInterpreterResizeInputTensor(TfLiteInterpreter* interpreter,
                                                int32_t input_index,
                                                const int* input_dims,
                                                int32_t input_dims_size) {
  std::vector<int> dims{input_dims, input_dims + input_dims_size};
  return interpreter->impl->ResizeInputTensor(
      interpreter->impl->inputs()[input_index], dims);
}

TfLiteStatus TfLiteInterpreterAllocateTensors(TfLiteInterpreter* interpreter) {
  return interpreter->impl->AllocateTensors();
}

TfLiteStatus TfLiteInterpreterInvoke(TfLiteInterpreter* interpreter) {
  if (interpreter->enable_delegate_fallback) {
    return tflite::delegates::InterpreterUtils::InvokeWithCPUFallback(
        interpreter->impl.get());
  } else {
    return interpreter->impl->Invoke();
  }
}

int32_t TfLiteInterpreterGetOutputTensorCount(
    const TfLiteInterpreter* interpreter) {
  return static_cast<int32_t>(interpreter->impl->outputs().size());
}

const TfLiteTensor* TfLiteInterpreterGetOutputTensor(
    const TfLiteInterpreter* interpreter, int32_t output_index) {
  return interpreter->impl->tensor(interpreter->impl->outputs()[output_index]);
}

TfLiteType TfLiteTensorType(const TfLiteTensor* tensor) { return tensor->type; }

int32_t TfLiteTensorNumDims(const TfLiteTensor* tensor) {
  return tensor->dims->size;
}

int32_t TfLiteTensorDim(const TfLiteTensor* tensor, int32_t dim_index) {
  return tensor->dims->data[dim_index];
}

size_t TfLiteTensorByteSize(const TfLiteTensor* tensor) {
  return tensor->bytes;
}

void* TfLiteTensorData(const TfLiteTensor* tensor) {
  return static_cast<void*>(tensor->data.raw);
}

const char* TfLiteTensorName(const TfLiteTensor* tensor) {
  return tensor->name;
}

TfLiteQuantizationParams TfLiteTensorQuantizationParams(
    const TfLiteTensor* tensor) {
  return tensor->params;
}

TfLiteStatus TfLiteTensorCopyFromBuffer(TfLiteTensor* tensor,
                                        const void* input_data,
                                        size_t input_data_size) {
  if (tensor->bytes != input_data_size) {
    return kTfLiteError;
  }
  memcpy(tensor->data.raw, input_data, input_data_size);
  return kTfLiteOk;
}

TfLiteStatus TfLiteTensorCopyToBuffer(const TfLiteTensor* tensor,
                                      void* output_data,
                                      size_t output_data_size) {
  if (tensor->bytes != output_data_size) {
    return kTfLiteError;
  }
  memcpy(output_data, tensor->data.raw, output_data_size);
  return kTfLiteOk;
}

// LINT.ThenChange(//tensorflow/lite/experimental/examples/unity/TensorFlowLitePlugin/Assets/TensorFlowLite/SDK/Scripts/Interpreter.cs)

}  // extern "C"

namespace tflite {
namespace internal {

TfLiteInterpreter* InterpreterCreateWithOpResolver(
    const TfLiteModel* model, const TfLiteInterpreterOptions* optional_options,
    tflite::MutableOpResolver* mutable_resolver) {
  TFLITE_DCHECK_NE(mutable_resolver, nullptr);
  if (!model || !model->impl) {
    return nullptr;
  }

  std::unique_ptr<tflite::ErrorReporter> optional_error_reporter;
  if (optional_options &&
      optional_options->error_reporter_callback.error_reporter != nullptr) {
    optional_error_reporter.reset(
        new CallbackErrorReporter(optional_options->error_reporter_callback));
  }

  // By default, we use the provided mutable_op_resolver, adding any builtin or
  // custom ops registered with `TfLiteInterpreterOptionsAddBuiltinOp` and/or
  // `TfLiteInterpreterOptionsAddCustomOp`.
  tflite::OpResolver* op_resolver = mutable_resolver;
  if (optional_options) {
    mutable_resolver->AddAll(optional_options->mutable_op_resolver);
  }
  // However, if `TfLiteInterpreterOptionsSetOpResolver` has been called with
  // a non-null callback parameter, then we instead use a
  // `CallbackOpResolver` that will forward to the callbacks provided there.
  CallbackOpResolver callback_op_resolver;
  if (optional_options &&
      (optional_options->op_resolver_callbacks.find_builtin_op != nullptr ||
       optional_options->op_resolver_callbacks.find_custom_op != nullptr)) {
    callback_op_resolver.SetCallbacks(optional_options->op_resolver_callbacks);
    op_resolver = &callback_op_resolver;
  }

  tflite::ErrorReporter* error_reporter = optional_error_reporter
                                              ? optional_error_reporter.get()
                                              : tflite::DefaultErrorReporter();
  tflite::InterpreterBuilder builder(model->impl->GetModel(), *op_resolver,
                                     error_reporter);

  std::unique_ptr<tflite::Interpreter> interpreter;
  if (builder(&interpreter) != kTfLiteOk) {
    return nullptr;
  }

  if (optional_options) {
    if (optional_options->num_threads !=
        TfLiteInterpreterOptions::kDefaultNumThreads) {
      interpreter->SetNumThreads(optional_options->num_threads);
    }

    if (optional_options->use_nnapi) {
      if (interpreter->ModifyGraphWithDelegate(tflite::NnApiDelegate()) !=
          kTfLiteOk) {
        return nullptr;
      }
    }

    for (auto* delegate : optional_options->delegates) {
      if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) {
        return nullptr;
      }
    }
  }

  bool enable_delegate_fallback =
      optional_options != nullptr && optional_options->enable_delegate_fallback;

  return new TfLiteInterpreter{model->impl, std::move(optional_error_reporter),
                               std::move(interpreter),
                               enable_delegate_fallback};
}

}  // namespace internal
}  // namespace tflite
<commit_msg>Remove unnecessary cast in TfLiteTensorData.<commit_after>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/c/c_api.h"

#include <memory>

#include "tensorflow/lite/builtin_ops.h"
#include "tensorflow/lite/c/c_api_internal.h"
#include "tensorflow/lite/delegates/interpreter_utils.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate.h"
#include "tensorflow/lite/error_reporter.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/internal/compatibility.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/version.h"

namespace {
class CallbackErrorReporter : public tflite::ErrorReporter {
 public:
  explicit CallbackErrorReporter(TfLiteErrorReporterCallback callback)
      : callback_(callback) {}

  int Report(const char* format, va_list args) override {
    callback_.error_reporter(callback_.user_data, format, args);
    return 0;
  }

 private:
  TfLiteErrorReporterCallback callback_;
};

/// `CallbackOpResolver` is a (C++) `tflite::OpResolver` that forwards the
/// methods to (C ABI) callback functions from a `TfLiteOpResolverCallbacks`
/// struct.
///
/// The SetCallbacks method must be called before calling any of the FindOp
/// methods.
class CallbackOpResolver : public ::tflite::OpResolver {
 public:
  CallbackOpResolver() {}
  void SetCallbacks(
      const struct TfLiteOpResolverCallbacks& op_resolver_callbacks) {
    op_resolver_callbacks_ = op_resolver_callbacks;
  }
  const TfLiteRegistration* FindOp(tflite::BuiltinOperator op,
                                   int version) const override {
    if (op_resolver_callbacks_.find_builtin_op == nullptr) {
      return nullptr;
    }
    return op_resolver_callbacks_.find_builtin_op(
        op_resolver_callbacks_.user_data,
        static_cast<TfLiteBuiltinOperator>(op), version);
  }
  const TfLiteRegistration* FindOp(const char* op, int version) const override {
    if (op_resolver_callbacks_.find_custom_op == nullptr) {
      return nullptr;
    }
    return op_resolver_callbacks_.find_custom_op(
        op_resolver_callbacks_.user_data, op, version);
  }

 private:
  CallbackOpResolver(const CallbackOpResolver&) = delete;
  CallbackOpResolver& operator=(const CallbackOpResolver&) = delete;

  struct TfLiteOpResolverCallbacks op_resolver_callbacks_ = {};
};

}  // namespace

extern "C" {

// LINT.IfChange

const char* TfLiteVersion() { return TFLITE_VERSION_STRING; }

TfLiteModel* TfLiteModelCreate(const void* model_data, size_t model_size) {
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(
      static_cast<const char*>(model_data), model_size);
  std::shared_ptr<const tflite::FlatBufferModel> shared_model(model.release());
  return shared_model ? new TfLiteModel{std::move(shared_model)} : nullptr;
}

TfLiteModel* TfLiteModelCreateFromFile(const char* model_path) {
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromFile(model_path);
  std::shared_ptr<const tflite::FlatBufferModel> shared_model(model.release());
  return shared_model ? new TfLiteModel{std::move(shared_model)} : nullptr;
}

void TfLiteModelDelete(TfLiteModel* model) { delete model; }

TfLiteInterpreterOptions* TfLiteInterpreterOptionsCreate() {
  return new TfLiteInterpreterOptions{};
}

void TfLiteInterpreterOptionsDelete(TfLiteInterpreterOptions* options) {
  delete options;
}

void TfLiteInterpreterOptionsSetNumThreads(TfLiteInterpreterOptions* options,
                                           int32_t num_threads) {
  options->num_threads = num_threads;
}

void TfLiteInterpreterOptionsAddDelegate(TfLiteInterpreterOptions* options,
                                         TfLiteDelegate* delegate) {
  options->delegates.push_back(delegate);
}

void TfLiteInterpreterOptionsSetErrorReporter(
    TfLiteInterpreterOptions* options,
    void (*reporter)(void* user_data, const char* format, va_list args),
    void* user_data) {
  options->error_reporter_callback.error_reporter = reporter;
  options->error_reporter_callback.user_data = user_data;
}

TfLiteInterpreter* TfLiteInterpreterCreate(
    const TfLiteModel* model,
    const TfLiteInterpreterOptions* optional_options) {
  tflite::ops::builtin::BuiltinOpResolver resolver;
  return tflite::internal::InterpreterCreateWithOpResolver(
      model, optional_options, &resolver);
}

void TfLiteInterpreterDelete(TfLiteInterpreter* interpreter) {
  delete interpreter;
}

int32_t TfLiteInterpreterGetInputTensorCount(
    const TfLiteInterpreter* interpreter) {
  return static_cast<int32_t>(interpreter->impl->inputs().size());
}

TfLiteTensor* TfLiteInterpreterGetInputTensor(
    const TfLiteInterpreter* interpreter, int32_t input_index) {
  return interpreter->impl->tensor(interpreter->impl->inputs()[input_index]);
}

TfLiteStatus TfLiteInterpreterResizeInputTensor(TfLiteInterpreter* interpreter,
                                                int32_t input_index,
                                                const int* input_dims,
                                                int32_t input_dims_size) {
  std::vector<int> dims{input_dims, input_dims + input_dims_size};
  return interpreter->impl->ResizeInputTensor(
      interpreter->impl->inputs()[input_index], dims);
}

TfLiteStatus TfLiteInterpreterAllocateTensors(TfLiteInterpreter* interpreter) {
  return interpreter->impl->AllocateTensors();
}

TfLiteStatus TfLiteInterpreterInvoke(TfLiteInterpreter* interpreter) {
  if (interpreter->enable_delegate_fallback) {
    return tflite::delegates::InterpreterUtils::InvokeWithCPUFallback(
        interpreter->impl.get());
  } else {
    return interpreter->impl->Invoke();
  }
}

int32_t TfLiteInterpreterGetOutputTensorCount(
    const TfLiteInterpreter* interpreter) {
  return static_cast<int32_t>(interpreter->impl->outputs().size());
}

const TfLiteTensor* TfLiteInterpreterGetOutputTensor(
    const TfLiteInterpreter* interpreter, int32_t output_index) {
  return interpreter->impl->tensor(interpreter->impl->outputs()[output_index]);
}

TfLiteType TfLiteTensorType(const TfLiteTensor* tensor) { return tensor->type; }

int32_t TfLiteTensorNumDims(const TfLiteTensor* tensor) {
  return tensor->dims->size;
}

int32_t TfLiteTensorDim(const TfLiteTensor* tensor, int32_t dim_index) {
  return tensor->dims->data[dim_index];
}

size_t TfLiteTensorByteSize(const TfLiteTensor* tensor) {
  return tensor->bytes;
}

void* TfLiteTensorData(const TfLiteTensor* tensor) { return tensor->data.raw; }

const char* TfLiteTensorName(const TfLiteTensor* tensor) {
  return tensor->name;
}

TfLiteQuantizationParams TfLiteTensorQuantizationParams(
    const TfLiteTensor* tensor) {
  return tensor->params;
}

TfLiteStatus TfLiteTensorCopyFromBuffer(TfLiteTensor* tensor,
                                        const void* input_data,
                                        size_t input_data_size) {
  if (tensor->bytes != input_data_size) {
    return kTfLiteError;
  }
  memcpy(tensor->data.raw, input_data, input_data_size);
  return kTfLiteOk;
}

TfLiteStatus TfLiteTensorCopyToBuffer(const TfLiteTensor* tensor,
                                      void* output_data,
                                      size_t output_data_size) {
  if (tensor->bytes != output_data_size) {
    return kTfLiteError;
  }
  memcpy(output_data, tensor->data.raw, output_data_size);
  return kTfLiteOk;
}

// LINT.ThenChange(//tensorflow/lite/experimental/examples/unity/TensorFlowLitePlugin/Assets/TensorFlowLite/SDK/Scripts/Interpreter.cs)

}  // extern "C"

namespace tflite {
namespace internal {

TfLiteInterpreter* InterpreterCreateWithOpResolver(
    const TfLiteModel* model, const TfLiteInterpreterOptions* optional_options,
    tflite::MutableOpResolver* mutable_resolver) {
  TFLITE_DCHECK_NE(mutable_resolver, nullptr);
  if (!model || !model->impl) {
    return nullptr;
  }

  std::unique_ptr<tflite::ErrorReporter> optional_error_reporter;
  if (optional_options &&
      optional_options->error_reporter_callback.error_reporter != nullptr) {
    optional_error_reporter.reset(
        new CallbackErrorReporter(optional_options->error_reporter_callback));
  }

  // By default, we use the provided mutable_op_resolver, adding any builtin or
  // custom ops registered with `TfLiteInterpreterOptionsAddBuiltinOp` and/or
  // `TfLiteInterpreterOptionsAddCustomOp`.
  tflite::OpResolver* op_resolver = mutable_resolver;
  if (optional_options) {
    mutable_resolver->AddAll(optional_options->mutable_op_resolver);
  }
  // However, if `TfLiteInterpreterOptionsSetOpResolver` has been called with
  // a non-null callback parameter, then we instead use a
  // `CallbackOpResolver` that will forward to the callbacks provided there.
  CallbackOpResolver callback_op_resolver;
  if (optional_options &&
      (optional_options->op_resolver_callbacks.find_builtin_op != nullptr ||
       optional_options->op_resolver_callbacks.find_custom_op != nullptr)) {
    callback_op_resolver.SetCallbacks(optional_options->op_resolver_callbacks);
    op_resolver = &callback_op_resolver;
  }

  tflite::ErrorReporter* error_reporter = optional_error_reporter
                                              ? optional_error_reporter.get()
                                              : tflite::DefaultErrorReporter();
  tflite::InterpreterBuilder builder(model->impl->GetModel(), *op_resolver,
                                     error_reporter);

  std::unique_ptr<tflite::Interpreter> interpreter;
  if (builder(&interpreter) != kTfLiteOk) {
    return nullptr;
  }

  if (optional_options) {
    if (optional_options->num_threads !=
        TfLiteInterpreterOptions::kDefaultNumThreads) {
      interpreter->SetNumThreads(optional_options->num_threads);
    }

    if (optional_options->use_nnapi) {
      if (interpreter->ModifyGraphWithDelegate(tflite::NnApiDelegate()) !=
          kTfLiteOk) {
        return nullptr;
      }
    }

    for (auto* delegate : optional_options->delegates) {
      if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) {
        return nullptr;
      }
    }
  }

  bool enable_delegate_fallback =
      optional_options != nullptr && optional_options->enable_delegate_fallback;

  return new TfLiteInterpreter{model->impl, std::move(optional_error_reporter),
                               std::move(interpreter),
                               enable_delegate_fallback};
}

}  // namespace internal
}  // namespace tflite
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>
#include <vector>

#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/dump_accessibility_tree_helper.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/test_utils.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "content/shell/shell.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  static const char kCommentToken = '#';
  static const char* kMarkSkipFile = "#<skip";
  static const char* kMarkEndOfFile = "<-- End-of-file -->";
  static const char* kSignalDiff = "*";
} // namespace

namespace content {

// This test takes a snapshot of the platform BrowserAccessibility tree and
// tests it against an expected baseline.
//
// The flow of the test is as outlined below.
// 1. Load an html file from chrome/test/data/accessibility.
// 2. Read the expectation.
// 3. Browse to the page and serialize the platform specific tree into a human
//    readable string.
// 4. Perform a comparison between actual and expected and fail if they do not
//    exactly match.
class DumpAccessibilityTreeTest : public ContentBrowserTest {
 public:
  // Utility helper that does a comment aware equality check.
  // Returns array of lines from expected file which are different.
  std::vector<int> DiffLines(std::vector<std::string>& expected_lines,
                             std::vector<std::string>& actual_lines) {
    int actual_lines_count = actual_lines.size();
    int expected_lines_count = expected_lines.size();
    std::vector<int> diff_lines;
    int i = 0, j = 0;
    while (i < actual_lines_count && j < expected_lines_count) {
      if (expected_lines[j].size() == 0 ||
          expected_lines[j][0] == kCommentToken) {
        // Skip comment lines and blank lines in expected output.
        ++j;
        continue;
      }

      if (actual_lines[i] != expected_lines[j])
        diff_lines.push_back(j);
      ++i;
      ++j;
    }

    // Actual file has been fully checked.
    return diff_lines;
  }

  void AddDefaultFilters(std::set<string16>* allow_filters,
                         std::set<string16>* deny_filters) {
    allow_filters->insert(ASCIIToUTF16("FOCUSABLE"));
    allow_filters->insert(ASCIIToUTF16("READONLY"));
  }

  void ParseFilters(const std::string& test_html,
                    std::set<string16>* allow_filters,
                    std::set<string16>* deny_filters) {
    std::vector<std::string> lines;
    base::SplitString(test_html, '\n', &lines);
    for (std::vector<std::string>::const_iterator iter = lines.begin();
         iter != lines.end();
         ++iter) {
      const std::string& line = *iter;
      const std::string& allow_str = helper_.GetAllowString();
      const std::string& deny_str = helper_.GetDenyString();
      if (StartsWithASCII(line, allow_str, true))
        allow_filters->insert(UTF8ToUTF16(line.substr(allow_str.size())));
      else if (StartsWithASCII(line, deny_str, true))
        deny_filters->insert(UTF8ToUTF16(line.substr(deny_str.size())));
    }
  }

  void RunTest(const FilePath::CharType* file_path);

  DumpAccessibilityTreeHelper helper_;
};

void DumpAccessibilityTreeTest::RunTest(const FilePath::CharType* file_path) {
  NavigateToURL(shell(), GURL("about:blank"));
  RenderWidgetHostViewPort* host_view = static_cast<RenderWidgetHostViewPort*>(
      shell()->web_contents()->GetRenderWidgetHostView());
  RenderWidgetHostImpl* host =
      RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
  RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(host);
  view_host->set_save_accessibility_tree_for_testing(true);
  view_host->SetAccessibilityMode(AccessibilityModeComplete);

  // Setup test paths.
  FilePath dir_test_data;
  EXPECT_TRUE(PathService::Get(DIR_TEST_DATA, &dir_test_data));
  FilePath test_path(dir_test_data.Append(FILE_PATH_LITERAL("accessibility")));
  EXPECT_TRUE(file_util::PathExists(test_path))
      << test_path.LossyDisplayName();

  FilePath html_file = test_path.Append(FilePath(file_path));
  // Output the test path to help anyone who encounters a failure and needs
  // to know where to look.
  printf("Testing: %s\n", html_file.MaybeAsASCII().c_str());

  std::string html_contents;
  file_util::ReadFileToString(html_file, &html_contents);

  // Parse filters in the test file.
  std::set<string16> allow_filters;
  std::set<string16> deny_filters;
  AddDefaultFilters(&allow_filters, &deny_filters);
  ParseFilters(html_contents, &allow_filters, &deny_filters);
  helper_.SetFilters(allow_filters, deny_filters);

  // Read the expected file.
  std::string expected_contents_raw;
  FilePath expected_file =
    FilePath(html_file.RemoveExtension().value() +
             helper_.GetExpectedFileSuffix());
  file_util::ReadFileToString(
      expected_file,
      &expected_contents_raw);

  // Tolerate Windows-style line endings (\r\n) in the expected file:
  // normalize by deleting all \r from the file (if any) to leave only \n.
  std::string expected_contents;
  RemoveChars(expected_contents_raw, "\r", &expected_contents);

  if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) {
    printf("Skipping this test on this platform.\n");
    return;
  }

  // Load the page.
  WindowedNotificationObserver tree_updated_observer(
      NOTIFICATION_ACCESSIBILITY_LOAD_COMPLETE,
      NotificationService::AllSources());
  string16 html_contents16;
  html_contents16 = UTF8ToUTF16(html_contents);
  GURL url = GetTestUrl("accessibility",
                        html_file.BaseName().MaybeAsASCII().c_str());
  NavigateToURL(shell(), url);

  // Wait for the tree.
  tree_updated_observer.Wait();

  // Perform a diff (or write the initial baseline).
  string16 actual_contents_utf16;
  helper_.DumpAccessibilityTree(
      host_view->GetBrowserAccessibilityManager()->GetRoot(),
      &actual_contents_utf16);
  std::string actual_contents = UTF16ToUTF8(actual_contents_utf16);
  std::vector<std::string> actual_lines, expected_lines;
  Tokenize(actual_contents, "\n", &actual_lines);
  Tokenize(expected_contents, "\n", &expected_lines);
  // Marking the end of the file with a line of text ensures that
  // file length differences are found.
  expected_lines.push_back(kMarkEndOfFile);
  actual_lines.push_back(kMarkEndOfFile);

  std::vector<int> diff_lines = DiffLines(expected_lines, actual_lines);
  bool is_different = diff_lines.size() > 0;
  EXPECT_FALSE(is_different);
  if (is_different) {
    // Mark the expected lines which did not match actual output with a *.
    printf("* Line Expected\n");
    printf("- ---- --------\n");
    for (int line = 0, diff_index = 0;
         line < static_cast<int>(expected_lines.size());
         ++line) {
      bool is_diff = false;
      if (diff_index < static_cast<int>(diff_lines.size()) &&
          diff_lines[diff_index] == line) {
        is_diff = true;
        ++ diff_index;
      }
      printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1,
             expected_lines[line].c_str());
    }
    printf("\nActual\n");
    printf("------\n");
    printf("%s\n", actual_contents.c_str());
  }

  if (!file_util::PathExists(expected_file)) {
    FilePath actual_file =
      FilePath(html_file.RemoveExtension().value() +
               helper_.GetActualFileSuffix());

    EXPECT_TRUE(file_util::WriteFile(
        actual_file, actual_contents.c_str(), actual_contents.size()));

    ADD_FAILURE() << "No expectation found. Create it by doing:\n"
                  << "mv " << actual_file.LossyDisplayName() << " "
                  << expected_file.LossyDisplayName();
  }
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityA) {
  RunTest(FILE_PATH_LITERAL("a.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAName) {
  RunTest(FILE_PATH_LITERAL("a-name.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAOnclick) {
  RunTest(FILE_PATH_LITERAL("a-onclick.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityAriaApplication) {
  RunTest(FILE_PATH_LITERAL("aria-application.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaCombobox) {
  RunTest(FILE_PATH_LITERAL("aria-combobox.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaMenu) {
  RunTest(FILE_PATH_LITERAL("aria-menu.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAWithImg) {
  RunTest(FILE_PATH_LITERAL("a-with-img.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityButtonNameCalc) {
  RunTest(FILE_PATH_LITERAL("button-name-calc.html"));
}

// TODO(dmazzoni): rebaseline and enable after this WebKit change is rolled:
// https://bugs.webkit.org/show_bug.cgi?id=96323
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       DISABLED_AccessibilityCanvas) {
  RunTest(FILE_PATH_LITERAL("canvas.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityCheckboxNameCalc) {
  RunTest(FILE_PATH_LITERAL("checkbox-name-calc.html"));
}

// TODO(dimich): Started to fail in Chrome r149732 (crbug 140397)
#if defined(OS_WIN)
#define MAYBE_AccessibilityContenteditableDescendants \
    DISABLED_AccessibilityContenteditableDescendants
#else
#define MAYBE_AccessibilityContenteditableDescendants \
    AccessibilityContenteditableDescendants
#endif

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityDiv) {
  RunTest(FILE_PATH_LITERAL("div.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       MAYBE_AccessibilityContenteditableDescendants) {
  RunTest(FILE_PATH_LITERAL("contenteditable-descendants.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityFooter) {
  RunTest(FILE_PATH_LITERAL("footer.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityForm) {
  RunTest(FILE_PATH_LITERAL("form.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityHR) {
  RunTest(FILE_PATH_LITERAL("hr.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputRange) {
  RunTest(FILE_PATH_LITERAL("input-range.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityInputTextNameCalc) {
  RunTest(FILE_PATH_LITERAL("input-text-name-calc.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityLabel) {
  RunTest(FILE_PATH_LITERAL("label.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityListMarkers) {
  RunTest(FILE_PATH_LITERAL("list-markers.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityP) {
  RunTest(FILE_PATH_LITERAL("p.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilitySpinButton) {
  RunTest(FILE_PATH_LITERAL("spinbutton.html"));
}

// TODO(dmazzoni): rebaseline and enable after this WebKit change is rolled:
// https://bugs.webkit.org/show_bug.cgi?id=96323
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       DISABLED_AccessibilityToggleButton) {
  RunTest(FILE_PATH_LITERAL("togglebutton.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityUl) {
  RunTest(FILE_PATH_LITERAL("ul.html"));
}

}  // namespace content
<commit_msg>Disable AccessibilityAriaCombobox test to avoid blocking the WebKit roll<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>
#include <vector>

#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/dump_accessibility_tree_helper.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/test_utils.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "content/shell/shell.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  static const char kCommentToken = '#';
  static const char* kMarkSkipFile = "#<skip";
  static const char* kMarkEndOfFile = "<-- End-of-file -->";
  static const char* kSignalDiff = "*";
} // namespace

namespace content {

// This test takes a snapshot of the platform BrowserAccessibility tree and
// tests it against an expected baseline.
//
// The flow of the test is as outlined below.
// 1. Load an html file from chrome/test/data/accessibility.
// 2. Read the expectation.
// 3. Browse to the page and serialize the platform specific tree into a human
//    readable string.
// 4. Perform a comparison between actual and expected and fail if they do not
//    exactly match.
class DumpAccessibilityTreeTest : public ContentBrowserTest {
 public:
  // Utility helper that does a comment aware equality check.
  // Returns array of lines from expected file which are different.
  std::vector<int> DiffLines(std::vector<std::string>& expected_lines,
                             std::vector<std::string>& actual_lines) {
    int actual_lines_count = actual_lines.size();
    int expected_lines_count = expected_lines.size();
    std::vector<int> diff_lines;
    int i = 0, j = 0;
    while (i < actual_lines_count && j < expected_lines_count) {
      if (expected_lines[j].size() == 0 ||
          expected_lines[j][0] == kCommentToken) {
        // Skip comment lines and blank lines in expected output.
        ++j;
        continue;
      }

      if (actual_lines[i] != expected_lines[j])
        diff_lines.push_back(j);
      ++i;
      ++j;
    }

    // Actual file has been fully checked.
    return diff_lines;
  }

  void AddDefaultFilters(std::set<string16>* allow_filters,
                         std::set<string16>* deny_filters) {
    allow_filters->insert(ASCIIToUTF16("FOCUSABLE"));
    allow_filters->insert(ASCIIToUTF16("READONLY"));
  }

  void ParseFilters(const std::string& test_html,
                    std::set<string16>* allow_filters,
                    std::set<string16>* deny_filters) {
    std::vector<std::string> lines;
    base::SplitString(test_html, '\n', &lines);
    for (std::vector<std::string>::const_iterator iter = lines.begin();
         iter != lines.end();
         ++iter) {
      const std::string& line = *iter;
      const std::string& allow_str = helper_.GetAllowString();
      const std::string& deny_str = helper_.GetDenyString();
      if (StartsWithASCII(line, allow_str, true))
        allow_filters->insert(UTF8ToUTF16(line.substr(allow_str.size())));
      else if (StartsWithASCII(line, deny_str, true))
        deny_filters->insert(UTF8ToUTF16(line.substr(deny_str.size())));
    }
  }

  void RunTest(const FilePath::CharType* file_path);

  DumpAccessibilityTreeHelper helper_;
};

void DumpAccessibilityTreeTest::RunTest(const FilePath::CharType* file_path) {
  NavigateToURL(shell(), GURL("about:blank"));
  RenderWidgetHostViewPort* host_view = static_cast<RenderWidgetHostViewPort*>(
      shell()->web_contents()->GetRenderWidgetHostView());
  RenderWidgetHostImpl* host =
      RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
  RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(host);
  view_host->set_save_accessibility_tree_for_testing(true);
  view_host->SetAccessibilityMode(AccessibilityModeComplete);

  // Setup test paths.
  FilePath dir_test_data;
  EXPECT_TRUE(PathService::Get(DIR_TEST_DATA, &dir_test_data));
  FilePath test_path(dir_test_data.Append(FILE_PATH_LITERAL("accessibility")));
  EXPECT_TRUE(file_util::PathExists(test_path))
      << test_path.LossyDisplayName();

  FilePath html_file = test_path.Append(FilePath(file_path));
  // Output the test path to help anyone who encounters a failure and needs
  // to know where to look.
  printf("Testing: %s\n", html_file.MaybeAsASCII().c_str());

  std::string html_contents;
  file_util::ReadFileToString(html_file, &html_contents);

  // Parse filters in the test file.
  std::set<string16> allow_filters;
  std::set<string16> deny_filters;
  AddDefaultFilters(&allow_filters, &deny_filters);
  ParseFilters(html_contents, &allow_filters, &deny_filters);
  helper_.SetFilters(allow_filters, deny_filters);

  // Read the expected file.
  std::string expected_contents_raw;
  FilePath expected_file =
    FilePath(html_file.RemoveExtension().value() +
             helper_.GetExpectedFileSuffix());
  file_util::ReadFileToString(
      expected_file,
      &expected_contents_raw);

  // Tolerate Windows-style line endings (\r\n) in the expected file:
  // normalize by deleting all \r from the file (if any) to leave only \n.
  std::string expected_contents;
  RemoveChars(expected_contents_raw, "\r", &expected_contents);

  if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) {
    printf("Skipping this test on this platform.\n");
    return;
  }

  // Load the page.
  WindowedNotificationObserver tree_updated_observer(
      NOTIFICATION_ACCESSIBILITY_LOAD_COMPLETE,
      NotificationService::AllSources());
  string16 html_contents16;
  html_contents16 = UTF8ToUTF16(html_contents);
  GURL url = GetTestUrl("accessibility",
                        html_file.BaseName().MaybeAsASCII().c_str());
  NavigateToURL(shell(), url);

  // Wait for the tree.
  tree_updated_observer.Wait();

  // Perform a diff (or write the initial baseline).
  string16 actual_contents_utf16;
  helper_.DumpAccessibilityTree(
      host_view->GetBrowserAccessibilityManager()->GetRoot(),
      &actual_contents_utf16);
  std::string actual_contents = UTF16ToUTF8(actual_contents_utf16);
  std::vector<std::string> actual_lines, expected_lines;
  Tokenize(actual_contents, "\n", &actual_lines);
  Tokenize(expected_contents, "\n", &expected_lines);
  // Marking the end of the file with a line of text ensures that
  // file length differences are found.
  expected_lines.push_back(kMarkEndOfFile);
  actual_lines.push_back(kMarkEndOfFile);

  std::vector<int> diff_lines = DiffLines(expected_lines, actual_lines);
  bool is_different = diff_lines.size() > 0;
  EXPECT_FALSE(is_different);
  if (is_different) {
    // Mark the expected lines which did not match actual output with a *.
    printf("* Line Expected\n");
    printf("- ---- --------\n");
    for (int line = 0, diff_index = 0;
         line < static_cast<int>(expected_lines.size());
         ++line) {
      bool is_diff = false;
      if (diff_index < static_cast<int>(diff_lines.size()) &&
          diff_lines[diff_index] == line) {
        is_diff = true;
        ++ diff_index;
      }
      printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1,
             expected_lines[line].c_str());
    }
    printf("\nActual\n");
    printf("------\n");
    printf("%s\n", actual_contents.c_str());
  }

  if (!file_util::PathExists(expected_file)) {
    FilePath actual_file =
      FilePath(html_file.RemoveExtension().value() +
               helper_.GetActualFileSuffix());

    EXPECT_TRUE(file_util::WriteFile(
        actual_file, actual_contents.c_str(), actual_contents.size()));

    ADD_FAILURE() << "No expectation found. Create it by doing:\n"
                  << "mv " << actual_file.LossyDisplayName() << " "
                  << expected_file.LossyDisplayName();
  }
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityA) {
  RunTest(FILE_PATH_LITERAL("a.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAName) {
  RunTest(FILE_PATH_LITERAL("a-name.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAOnclick) {
  RunTest(FILE_PATH_LITERAL("a-onclick.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityAriaApplication) {
  RunTest(FILE_PATH_LITERAL("aria-application.html"));
}

// Broken by http://trac.webkit.org/137512
// Tracked in http://crbug.com/165838
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       DISABLED_AccessibilityAriaCombobox) {
  RunTest(FILE_PATH_LITERAL("aria-combobox.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaMenu) {
  RunTest(FILE_PATH_LITERAL("aria-menu.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAWithImg) {
  RunTest(FILE_PATH_LITERAL("a-with-img.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityButtonNameCalc) {
  RunTest(FILE_PATH_LITERAL("button-name-calc.html"));
}

// TODO(dmazzoni): rebaseline and enable after this WebKit change is rolled:
// https://bugs.webkit.org/show_bug.cgi?id=96323
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       DISABLED_AccessibilityCanvas) {
  RunTest(FILE_PATH_LITERAL("canvas.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityCheckboxNameCalc) {
  RunTest(FILE_PATH_LITERAL("checkbox-name-calc.html"));
}

// TODO(dimich): Started to fail in Chrome r149732 (crbug 140397)
#if defined(OS_WIN)
#define MAYBE_AccessibilityContenteditableDescendants \
    DISABLED_AccessibilityContenteditableDescendants
#else
#define MAYBE_AccessibilityContenteditableDescendants \
    AccessibilityContenteditableDescendants
#endif

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityDiv) {
  RunTest(FILE_PATH_LITERAL("div.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       MAYBE_AccessibilityContenteditableDescendants) {
  RunTest(FILE_PATH_LITERAL("contenteditable-descendants.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityFooter) {
  RunTest(FILE_PATH_LITERAL("footer.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityForm) {
  RunTest(FILE_PATH_LITERAL("form.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityHR) {
  RunTest(FILE_PATH_LITERAL("hr.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputRange) {
  RunTest(FILE_PATH_LITERAL("input-range.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       AccessibilityInputTextNameCalc) {
  RunTest(FILE_PATH_LITERAL("input-text-name-calc.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityLabel) {
  RunTest(FILE_PATH_LITERAL("label.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityListMarkers) {
  RunTest(FILE_PATH_LITERAL("list-markers.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityP) {
  RunTest(FILE_PATH_LITERAL("p.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilitySpinButton) {
  RunTest(FILE_PATH_LITERAL("spinbutton.html"));
}

// TODO(dmazzoni): rebaseline and enable after this WebKit change is rolled:
// https://bugs.webkit.org/show_bug.cgi?id=96323
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                       DISABLED_AccessibilityToggleButton) {
  RunTest(FILE_PATH_LITERAL("togglebutton.html"));
}

IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityUl) {
  RunTest(FILE_PATH_LITERAL("ul.html"));
}

}  // namespace content
<|endoftext|>


<commit_before>/// @file
/// @author uentity
/// @date 30.08.2016
/// @brief Kernel logging subsystem impl
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include "kernel_logging_subsyst.h"
#include <spdlog/spdlog.h>
#include <unordered_map>

using namespace blue_sky::detail;

namespace {

template< typename... Sinks >
auto register_logger(const char* log_name, Sinks... sinks) {
	spdlog::sink_ptr S[] = { sinks... };
	std::shared_ptr< spdlog::logger > L(std::make_shared< spdlog::logger >(
		log_name, begin(S), end(S)
	));
	spdlog::register_logger(L);
	return L;
}

}

spdlog::logger& kernel_logging_subsyst::get_log(const char* log_name) {
	struct logs_container {
		// construct and set default logs formaat
		logs_container() :
			logs({
				{"out", register_logger("out",
					std::make_shared< spdlog::sinks::stdout_sink_mt >(),
					std::make_shared< spdlog::sinks::rotating_file_sink_mt >("blue_sky", "log", 1024*1024*5, 1)
				)},
				{"err", register_logger("err",
					std::make_shared< spdlog::sinks::stderr_sink_mt >(),
					std::make_shared< spdlog::sinks::rotating_file_sink_mt >("blue_sky_err", "log", 1024*1024*5, 1)
			)}})
		{
			for(auto& log : logs) {
				log.second->set_pattern("[%Y-%m-%d %T.%e] [%L] %v");
			}
		}

		spdlog::logger& operator[](const char* name) {
			return *logs.at(name);
		}

		std::unordered_map< std::string, std::shared_ptr< spdlog::logger > > logs;
	};

	// let's create C++11 thread-safe singleton as static variable
	// static variable would be initialized only in one thread!
	// we need to use VS2015 to support this
	static logs_container logs;

	return logs[log_name];
}

<commit_msg>log: fix logs constructors according to upstream changes<commit_after>/// @file
/// @author uentity
/// @date 30.08.2016
/// @brief Kernel logging subsystem impl
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include "kernel_logging_subsyst.h"
#include <spdlog/spdlog.h>
#include <unordered_map>

using namespace blue_sky::detail;

namespace {

template< typename... Sinks >
auto register_logger(const char* log_name, Sinks... sinks) {
	spdlog::sink_ptr S[] = { sinks... };
	std::shared_ptr< spdlog::logger > L(std::make_shared< spdlog::logger >(
		log_name, begin(S), end(S)
	));
	spdlog::register_logger(L);
	return L;
}

}

spdlog::logger& kernel_logging_subsyst::get_log(const char* log_name) {
	struct logs_container {
		// construct and set default logs formaat
		logs_container() :
			logs({
				{"out", register_logger("out",
					std::make_shared< spdlog::sinks::stdout_sink_mt >(),
					std::make_shared< spdlog::sinks::rotating_file_sink_mt >("blue_sky", 1024*1024*5, 1)
				)},
				{"err", register_logger("err",
					std::make_shared< spdlog::sinks::stderr_sink_mt >(),
					std::make_shared< spdlog::sinks::rotating_file_sink_mt >("blue_sky_err", 1024*1024*5, 1)
			)}})
		{
			for(auto& log : logs) {
				log.second->set_pattern("[%Y-%m-%d %T.%e] [%L] %v");
			}
		}

		spdlog::logger& operator[](const char* name) {
			return *logs.at(name);
		}

		std::unordered_map< std::string, std::shared_ptr< spdlog::logger > > logs;
	};

	// let's create C++11 thread-safe singleton as static variable
	// static variable would be initialized only in one thread!
	// we need to use VS2015 to support this
	static logs_container logs;

	return logs[log_name];
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(STLHELPERS_HEADER_GUARD_1357924680)
#define STLHELPERS_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include "PlatformSupportDefinitions.hpp"

#include <functional>

/**
 * Functor to delete objects, used in STL iteration algorithms.
 */
template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct DeleteFunctor : public unary_function<const T*, void>
#else
struct DeleteFunctor : public std::unary_function<const T*, void>
#endif
{
	/**
	 * Delete the object pointed to by argument.
	 *
	 * @param thePointer pointer to object to be deleted
	 */
	result_type
	operator()(argument_type	thePointer) const
	{
		delete thePointer;
	}
};

template<class T>
class array_auto_ptr
{
public:

	array_auto_ptr(T*	thePointer) :
		m_pointer(thePointer)
	{
	}

	~array_auto_ptr()
	{
		delete [] m_pointer;
	}

	T*
	get() const
	{
		return m_pointer;
	}

	T*
	release()
	{
		T* const	temp = m_pointer;

		m_pointer = 0;

		return temp;
	}

private:

	T*	m_pointer;
};

#if !defined(XALAN_SGI_BASED_STL)

/**
 * Functor to retrieve the key of a key-value pair in a map, used in STL
 * iteration algorithms.
 */
template <class PairType>
#if defined(XALAN_NO_NAMESPACES)
struct select1st : public unary_function<PairType, PairType::first_type>
#else
struct select1st : public std::unary_function<PairType, PairType::first_type>
#endif
{
	typedef typename PairType	value_type;

	/**
	 * Retrieve the key of a key-value pair.
	 *
	 * @param thePair key-value pair
	 * @return key
	 */
	typename result_type
	operator()(const typename argument_type&	thePair) const
	{
		return thePair.first;
	}
};

/**
 * Functor to retrieve the value of a key-value pair in a map, used in STL
 * iteration algorithms.
 */
template <class PairType>
#if defined(XALAN_NO_NAMESPACES)
struct select2nd : public unary_function<PairType, PairType::second_type>
#else
struct select2nd : public std::unary_function<PairType, PairType::second_type>
#endif
{
	typedef typename PairType	value_type;

	/**
	 * Retrieve the value of a key-value pair.
	 *
	 * @param thePair key-value pair
	 * @return value
	 */
	typename result_type
	operator()(const typename argument_type&	thePair) const
	{
		return thePair.second;
	}
};

#endif

/**
 * Functor to delete value objects in maps, used in STL iteration algorithms.
 */
template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct MapValueDeleteFunctor : public unary_function<const T::value_type&, void>
#else
struct MapValueDeleteFunctor : public std::unary_function<const typename T::value_type&, void>
#endif
{
	/**
	 * Delete the value object in a map value pair.  The value of the pair must
	 * be of pointer type.
	 *
	 * @param thePair key-value pair
	 */
	result_type
	operator()(argument_type	thePair) const
	{
		delete thePair.second;
	}
};

template<class T>
MapValueDeleteFunctor<T>
makeMapValueDeleteFunctor(const T&	/* theMap */)
{
	return MapValueDeleteFunctor<T>();
}

template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct MapKeyDeleteFunctor : public unary_function<const T::value_type&, void>
#else
struct MapKeyDeleteFunctor : public std::unary_function<const typename T::value_type&, void>
#endif
{
	/**
	 * Delete the value object in a map value pair.  The value of the pair must
	 * be of pointer type.
	 *
	 * @param thePair key-value pair
	 */
	result_type
	operator()(argument_type	thePair)
	{
		delete thePair.first;
	}
};

template<class T>
MapKeyDeleteFunctor<T>
makeMapKeyDeleteFunctor(const T&	/* theMap */)
{
	return MapKeyDeleteFunctor<T>();
}

/**
 * This functor is designed to compare 0-terminated arrays.  It substitutes
 * for the default less<type*> so that pointers to arrays can be compared,
 * rather than copies of arrays.  For example, you might want to use C-style
 * strings as keys in a map, rather than string objects.  The default
 * algorithm less<const char*> would just compare the pointers, and not the
 * vector of characters to which it points.  Using this algorithm instead of
 * the default will allow the map to work as expected.
 */
template<class T>
#if defined(XALAN_NO_NAMESPACES)
struct less_null_terminated_arrays : public binary_function<const T*, const T*, bool>
#else
struct less_null_terminated_arrays : public std::binary_function<const T*, const T*, bool>
#endif
{
	/**
	 * Compare the values of two objects.
	 *
	 *
	 * @param theLHS first object to compare
	 * @param theRHS second object to compare
	 * @return true if objects are the same
	 */
	result_type
	operator()(
			first_argument_type		theLHS,
			second_argument_type	theRHS) const
	{
		while(*theLHS && *theRHS)
		{
			if (*theLHS != *theRHS)
			{
				break;
			}
			else
			{
				theLHS++;
				theRHS++;
			}
		}

		return *theLHS < *theRHS ? true : false;
	}
};

#endif	// STLHELPERS_HEADER_GUARD_1357924680
<commit_msg>Added assignment operator and copy constructor to array_auto_ptr.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(STLHELPERS_HEADER_GUARD_1357924680)
#define STLHELPERS_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include "PlatformSupportDefinitions.hpp"

#include <functional>

/**
 * Functor to delete objects, used in STL iteration algorithms.
 */
template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct DeleteFunctor : public unary_function<const T*, void>
#else
struct DeleteFunctor : public std::unary_function<const T*, void>
#endif
{
	/**
	 * Delete the object pointed to by argument.
	 *
	 * @param thePointer pointer to object to be deleted
	 */
	result_type
	operator()(argument_type	thePointer) const
	{
		delete thePointer;
	}
};

// A class similar to auto_ptr, but for arrays.
template<class T>
class array_auto_ptr
{
public:

	array_auto_ptr(T*	thePointer = 0) :
		m_pointer(thePointer)
	{
	}

	array_auto_ptr(array_auto_ptr&	theSource) :
		m_pointer(theSource.release())
	{
	}

	array_auto_ptr&
	operator=(array_auto_ptr&	theRHS)
	{
		if (this != &theRHS)
		{
			delete m_pointer;

			m_pointer = theRHS.release();
		}

		return *this;
	}

	~array_auto_ptr()
	{
		delete [] m_pointer;
	}

	T*
	get() const
	{
		return m_pointer;
	}

	T*
	release()
	{
		T* const	temp = m_pointer;

		m_pointer = 0;

		return temp;
	}

private:

	T*	m_pointer;
};

#if !defined(XALAN_SGI_BASED_STL)

/**
 * Functor to retrieve the key of a key-value pair in a map, used in STL
 * iteration algorithms.
 */
template <class PairType>
#if defined(XALAN_NO_NAMESPACES)
struct select1st : public unary_function<PairType, PairType::first_type>
#else
struct select1st : public std::unary_function<PairType, PairType::first_type>
#endif
{
	typedef typename PairType	value_type;

	/**
	 * Retrieve the key of a key-value pair.
	 *
	 * @param thePair key-value pair
	 * @return key
	 */
	typename result_type
	operator()(const typename argument_type&	thePair) const
	{
		return thePair.first;
	}
};

/**
 * Functor to retrieve the value of a key-value pair in a map, used in STL
 * iteration algorithms.
 */
template <class PairType>
#if defined(XALAN_NO_NAMESPACES)
struct select2nd : public unary_function<PairType, PairType::second_type>
#else
struct select2nd : public std::unary_function<PairType, PairType::second_type>
#endif
{
	typedef typename PairType	value_type;

	/**
	 * Retrieve the value of a key-value pair.
	 *
	 * @param thePair key-value pair
	 * @return value
	 */
	typename result_type
	operator()(const typename argument_type&	thePair) const
	{
		return thePair.second;
	}
};

#endif

/**
 * Functor to delete value objects in maps, used in STL iteration algorithms.
 */
template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct MapValueDeleteFunctor : public unary_function<const T::value_type&, void>
#else
struct MapValueDeleteFunctor : public std::unary_function<const typename T::value_type&, void>
#endif
{
	/**
	 * Delete the value object in a map value pair.  The value of the pair must
	 * be of pointer type.
	 *
	 * @param thePair key-value pair
	 */
	result_type
	operator()(argument_type	thePair) const
	{
		delete thePair.second;
	}
};

template<class T>
MapValueDeleteFunctor<T>
makeMapValueDeleteFunctor(const T&	/* theMap */)
{
	return MapValueDeleteFunctor<T>();
}

template <class T>
#if defined(XALAN_NO_NAMESPACES)
struct MapKeyDeleteFunctor : public unary_function<const T::value_type&, void>
#else
struct MapKeyDeleteFunctor : public std::unary_function<const typename T::value_type&, void>
#endif
{
	/**
	 * Delete the value object in a map value pair.  The value of the pair must
	 * be of pointer type.
	 *
	 * @param thePair key-value pair
	 */
	result_type
	operator()(argument_type	thePair)
	{
		delete thePair.first;
	}
};

template<class T>
MapKeyDeleteFunctor<T>
makeMapKeyDeleteFunctor(const T&	/* theMap */)
{
	return MapKeyDeleteFunctor<T>();
}

/**
 * This functor is designed to compare 0-terminated arrays.  It substitutes
 * for the default less<type*> so that pointers to arrays can be compared,
 * rather than copies of arrays.  For example, you might want to use C-style
 * strings as keys in a map, rather than string objects.  The default
 * algorithm less<const char*> would just compare the pointers, and not the
 * vector of characters to which it points.  Using this algorithm instead of
 * the default will allow the map to work as expected.
 */
template<class T>
#if defined(XALAN_NO_NAMESPACES)
struct less_null_terminated_arrays : public binary_function<const T*, const T*, bool>
#else
struct less_null_terminated_arrays : public std::binary_function<const T*, const T*, bool>
#endif
{
	/**
	 * Compare the values of two objects.
	 *
	 *
	 * @param theLHS first object to compare
	 * @param theRHS second object to compare
	 * @return true if objects are the same
	 */
	result_type
	operator()(
			first_argument_type		theLHS,
			second_argument_type	theRHS) const
	{
		while(*theLHS && *theRHS)
		{
			if (*theLHS != *theRHS)
			{
				break;
			}
			else
			{
				theLHS++;
				theRHS++;
			}
		}

		return *theLHS < *theRHS ? true : false;
	}
};

#endif	// STLHELPERS_HEADER_GUARD_1357924680
<|endoftext|>