<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/scom/handleSpecialWakeup.C $                          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#include <stdint.h>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <trace/interface.H>

#include <targeting/common/commontargeting.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/util.H>

#include <scom/scomreasoncodes.H>
#include <initservice/initserviceif.H>

#ifdef __HOSTBOOT_RUNTIME
#include <runtime/rt_targeting.H>
#include <runtime/interface.h>
#endif // __HOSTBOOT_RUNTIME

#include <fapi2/plat_hwp_invoker.H>
#include <p9_cpu_special_wakeup.H>

extern "C"
{

// Trace definition
extern trace_desc_t* g_trac_scom;

using namespace TARGETING;
using namespace SCOM;

/**
 * @brief Enable and disable special wakeup for SCOM operations
 *   FSP:  Call the Host interface wakeup function for all core
 *         targets under the specified target, HOST wakeup bit is used
 *   BMC:  Call the wakeup HWP for the target type specified (EQ/EX/CORE),
 *         Proc type calls the HWP for all cores, FSP wakeup bit is used
 */
errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable)
{
    errlHndl_t l_errl = NULL;
    fapi2::ReturnCode l_rc;

    TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();

#ifdef __HOSTBOOT_RUNTIME
    // FSP
    if(INITSERVICE::spBaseServicesEnabled())
    {
        // Check for valid interface function
        if( g_hostInterfaces == NULL ||
            g_hostInterfaces->wakeup == NULL )
        {
            TRACFCOMP( g_trac_scom,
                       ERR_MRK"Hypervisor wakeup interface not linked");

            /*@
             * @errortype
             * @moduleid     SCOM_HANDLE_SPECIAL_WAKEUP
             * @reasoncode   SCOM_RUNTIME_INTERFACE_ERR
             * @userdata1    Target HUID
             * @userdata2    Wakeup Enable
             * @devdesc      Wakeup runtime interface not linked.
             */
            l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                             SCOM_HANDLE_SPECIAL_WAKEUP,
                                             SCOM_RUNTIME_INTERFACE_ERR,
                                             get_huid(i_target),
                                             i_enable);

            l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                                        HWAS::SRCI_PRIORITY_HIGH);

            return l_errl;
        }

        TargetHandleList pCoreList;

        // If the target is already a core just push it on the list
        if(l_type == TARGETING::TYPE_CORE)
        {
            pCoreList.clear();
            pCoreList.push_back(i_target);
        }
        else
        {
            getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE );
        }

        // Call wakeup on all core targets
        // Wakeup may be called twice for fused cores
        for ( auto pCore_it = pCoreList.begin();
              pCore_it != pCoreList.end();
              ++pCore_it )
        {
            // Runtime target id
            RT_TARG::rtChipId_t rtTargetId = 0;
            l_errl = RT_TARG::getRtTarget(*pCore_it, rtTargetId);
            if(l_errl)
            {
                break;
            }

            uint32_t mode;
            if(i_enable)
            {
                mode = HBRT_WKUP_FORCE_AWAKE;
            }
            else
            {
                mode = HBRT_WKUP_CLEAR_FORCE;
            }

            // Do the special wakeup
            int l_rc = g_hostInterfaces->wakeup(rtTargetId,mode);

            if(l_rc)
            {
                TRACFCOMP( g_trac_scom,ERR_MRK
                    "Hypervisor wakeup failed. "
                    "rc 0x%X target_huid 0x%llX rt_target_id 0x%llX mode %d",
                    l_rc, get_huid(*pCore_it), rtTargetId, mode );

                // convert rc to error log
                /*@
                 * @errortype
                 * @moduleid         SCOM_HANDLE_SPECIAL_WAKEUP
                 * @reasoncode       SCOM_RUNTIME_WAKEUP_ERR
                 * @userdata1        Hypervisor return code
                 * @userdata2[0:31]  Runtime Target ID
                 * @userdata2[32:63] Wakeup Mode
                 * @devdesc          Hypervisor wakeup failed.
                 */
                l_errl = new ERRORLOG::ErrlEntry(
                                            ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                            SCOM_HANDLE_SPECIAL_WAKEUP,
                                            SCOM_RUNTIME_WAKEUP_ERR,
                                            l_rc,
                                            TWO_UINT32_TO_UINT64(
                                                        rtTargetId, mode));

                l_errl->addHwCallout(i_target,
                                     HWAS::SRCI_PRIORITY_LOW,
                                     HWAS::NO_DECONFIG,
                                     HWAS::GARD_NULL);

                break;
            }
        }
    }

    // BMC
    else
    {
#endif // __HOSTBOOT_RUNTIME
        if(l_type == TARGETING::TYPE_PROC)
        {
            // Call wakeup on all core targets
            TargetHandleList pCoreList;
            getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE );

            for ( auto pCore_it = pCoreList.begin();
                  pCore_it != pCoreList.end();
                  ++pCore_it )
            {
                // To simplify, just call recursively with the core target
                l_errl = handleSpecialWakeup(*pCore_it, i_enable);
                if(l_errl)
                {
                    break;
                }
            }
            return l_errl;
        }

        // Need to handle multiple calls to enable special wakeup
        // Count attribute will keep track and disable when zero
        // Assume HBRT is single-threaded, so no issues with concurrency
        uint32_t l_count = (i_target)->getAttr<ATTR_SPCWKUP_COUNT>();

        if((l_count==0) && !i_enable)
        {
            TRACFCOMP( g_trac_scom,ERR_MRK
                "Disabling special wakeup on target with SPCWKUP_COUNT=0");

            /*@
             * @errortype
             * @moduleid         SCOM_HANDLE_SPECIAL_WAKEUP
             * @reasoncode       SCOM_SPCWKUP_COUNT_ERR
             * @userdata1        Target HUID
             * @userdata2[0:31]  Wakeup Enable
             * @userdata2[32:63] Wakeup Count
             * @devdesc          Disabling special wakeup when not enabled.
             */
            l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                             SCOM_HANDLE_SPECIAL_WAKEUP,
                                             SCOM_SPCWKUP_COUNT_ERR,
                                             get_huid(i_target),
                                             TWO_UINT32_TO_UINT64(
                                                        i_enable, l_count));

            l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                                        HWAS::SRCI_PRIORITY_LOW);

            errlCommit( l_errl, RUNTIME_COMP_ID );
        }

        // Only call the HWP if 0-->1 or 1-->0
        if( ((l_count==0) &&  i_enable) ||
            ((l_count==1) && !i_enable) )
        {
            // NOTE Regarding the entity type passed to the HWP:
            // There are 3 independent registers used to trigger a
            // special wakeup (FSP,HOST,OCC), we are using the FSP
            // bit because HOST/OCC are already in use.

            p9specialWakeup::PROC_SPCWKUP_OPS l_spcwkupType;
            p9specialWakeup::PROC_SPCWKUP_ENTITY l_spcwkupSrc;
            if(! INITSERVICE::spBaseServicesEnabled())
            {
                l_spcwkupSrc = p9specialWakeup::FSP;
            }
            else
            {
                l_spcwkupSrc = p9specialWakeup::HOST;
            }

            if(i_enable)
            {
                l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE;
            }
            else
            {
                l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE;
            }

            if(l_type == TARGETING::TYPE_EQ)
            {
                fapi2::Target<fapi2::TARGET_TYPE_EQ>
                    l_fapi_target(const_cast<TARGETING::Target*>(i_target));

                FAPI_EXEC_HWP(l_rc,
                              p9_cpu_special_wakeup_eq,
                              l_fapi_target,
                              l_spcwkupType,
                              l_spcwkupSrc );
                l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
            }
            else if(l_type == TARGETING::TYPE_EX)
            {
                fapi2::Target<fapi2::TARGET_TYPE_EX_CHIPLET>
                    l_fapi_target(const_cast<TARGETING::Target*>(i_target));

                FAPI_EXEC_HWP(l_rc,
                              p9_cpu_special_wakeup_ex,
                              l_fapi_target,
                              l_spcwkupType,
                              l_spcwkupSrc );
                l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
            }
            else if(l_type == TARGETING::TYPE_CORE)
            {
                fapi2::Target<fapi2::TARGET_TYPE_CORE>
                    l_fapi_target(const_cast<TARGETING::Target*>(i_target));

                FAPI_EXEC_HWP(l_rc,
                              p9_cpu_special_wakeup_core,
                              l_fapi_target,
                              l_spcwkupType,
                              l_spcwkupSrc );
                l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
            }

            if(l_errl)
            {
                TRACFCOMP( g_trac_scom,
                        "p9_cpu_special_wakeup ERROR :"
                        " Returning errorlog, reason=0x%x",
                        l_errl->reasonCode() );

                // Capture the target data in the elog
                ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl );
            }
        }

        // Update the counter
        if(!l_errl)
        {
            if(i_enable)
            {
                l_count++;
            }
            else
            {
                l_count--;
            }
            i_target->setAttr<ATTR_SPCWKUP_COUNT>(l_count);
        }
#ifdef __HOSTBOOT_RUNTIME
    }
#endif

    return l_errl;
}

}
<commit_msg>Use hostservice to do special wakeup at runtime for open-power systems<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/scom/handleSpecialWakeup.C $                          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#include <stdint.h>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <trace/interface.H>

#include <targeting/common/commontargeting.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/util.H>

#include <scom/scomreasoncodes.H>
#include <initservice/initserviceif.H>

#ifdef __HOSTBOOT_RUNTIME
#include <runtime/rt_targeting.H>
#include <runtime/interface.h>
#endif // __HOSTBOOT_RUNTIME

#include <fapi2/plat_hwp_invoker.H>
#include <p9_cpu_special_wakeup.H>

extern "C"
{

// Trace definition
extern trace_desc_t* g_trac_scom;

using namespace TARGETING;
using namespace SCOM;

/**
 * @brief Enable and disable special wakeup for SCOM operations
 *   FSP:  Call the Host interface wakeup function for all core
 *         targets under the specified target, HOST wakeup bit is used
 *   BMC:  Call the wakeup HWP for the target type specified (EQ/EX/CORE),
 *         Proc type calls the HWP for all cores, FSP wakeup bit is used
 */
errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable)
{
    errlHndl_t l_errl = NULL;
    fapi2::ReturnCode l_rc;

    TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();

#ifdef __HOSTBOOT_RUNTIME
    // FSP and BMC runtime use hostservice for wakeup

    // Check for valid interface function
    if( g_hostInterfaces == NULL ||
        g_hostInterfaces->wakeup == NULL )
    {
        TRACFCOMP( g_trac_scom,
                   ERR_MRK"Hypervisor wakeup interface not linked");

        /*@
         * @errortype
         * @moduleid     SCOM_HANDLE_SPECIAL_WAKEUP
         * @reasoncode   SCOM_RUNTIME_INTERFACE_ERR
         * @userdata1    Target HUID
         * @userdata2    Wakeup Enable
         * @devdesc      Wakeup runtime interface not linked.
         */
        l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                         SCOM_HANDLE_SPECIAL_WAKEUP,
                                         SCOM_RUNTIME_INTERFACE_ERR,
                                         get_huid(i_target),
                                         i_enable);

        l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                                    HWAS::SRCI_PRIORITY_HIGH);

        return l_errl;
    }

    TargetHandleList pCoreList;

    // If the target is already a core just push it on the list
    if(l_type == TARGETING::TYPE_CORE)
    {
        pCoreList.clear();
        pCoreList.push_back(i_target);
    }
    else
    {
        getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE );
    }

    // Call wakeup on all core targets
    // Wakeup may be called twice for fused cores
    for ( auto pCore_it = pCoreList.begin();
          pCore_it != pCoreList.end();
          ++pCore_it )
    {
        // Runtime target id
        RT_TARG::rtChipId_t rtTargetId = 0;
        l_errl = RT_TARG::getRtTarget(*pCore_it, rtTargetId);
        if(l_errl)
        {
            break;
        }

        uint32_t mode;
        if(i_enable)
        {
            mode = HBRT_WKUP_FORCE_AWAKE;
        }
        else
        {
            mode = HBRT_WKUP_CLEAR_FORCE;
        }

        // Do the special wakeup
        int l_rc = g_hostInterfaces->wakeup(rtTargetId,mode);

        if(l_rc)
        {
            TRACFCOMP( g_trac_scom,ERR_MRK
                "Hypervisor wakeup failed. "
                "rc 0x%X target_huid 0x%llX rt_target_id 0x%llX mode %d",
                l_rc, get_huid(*pCore_it), rtTargetId, mode );

            // convert rc to error log
            /*@
             * @errortype
             * @moduleid         SCOM_HANDLE_SPECIAL_WAKEUP
             * @reasoncode       SCOM_RUNTIME_WAKEUP_ERR
             * @userdata1        Hypervisor return code
             * @userdata2[0:31]  Runtime Target ID
             * @userdata2[32:63] Wakeup Mode
             * @devdesc          Hypervisor wakeup failed.
             */
            l_errl = new ERRORLOG::ErrlEntry(
                                        ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                        SCOM_HANDLE_SPECIAL_WAKEUP,
                                        SCOM_RUNTIME_WAKEUP_ERR,
                                        l_rc,
                                        TWO_UINT32_TO_UINT64(
                                                    rtTargetId, mode));

            l_errl->addHwCallout(i_target,
                                 HWAS::SRCI_PRIORITY_LOW,
                                 HWAS::NO_DECONFIG,
                                 HWAS::GARD_NULL);

            break;
        }
    }

#else
    // IPL time so use HWP for wakeup

    if(l_type == TARGETING::TYPE_PROC)
    {
        // Call wakeup on all core targets
        TargetHandleList pCoreList;
        getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE );

        for ( auto pCore_it = pCoreList.begin();
              pCore_it != pCoreList.end();
              ++pCore_it )
        {
            // To simplify, just call recursively with the core target
            l_errl = handleSpecialWakeup(*pCore_it, i_enable);
            if(l_errl)
            {
                break;
            }
        }
        return l_errl;
    }

    // Need to handle multiple calls to enable special wakeup
    // Count attribute will keep track and disable when zero
    // Assume HBRT is single-threaded, so no issues with concurrency
    uint32_t l_count = (i_target)->getAttr<ATTR_SPCWKUP_COUNT>();

    if((l_count==0) && !i_enable)
    {
        TRACFCOMP( g_trac_scom,ERR_MRK
            "Disabling special wakeup on target with SPCWKUP_COUNT=0");

        /*@
         * @errortype
         * @moduleid         SCOM_HANDLE_SPECIAL_WAKEUP
         * @reasoncode       SCOM_SPCWKUP_COUNT_ERR
         * @userdata1        Target HUID
         * @userdata2[0:31]  Wakeup Enable
         * @userdata2[32:63] Wakeup Count
         * @devdesc          Disabling special wakeup when not enabled.
         */
        l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
                                         SCOM_HANDLE_SPECIAL_WAKEUP,
                                         SCOM_SPCWKUP_COUNT_ERR,
                                         get_huid(i_target),
                                         TWO_UINT32_TO_UINT64(
                                                    i_enable, l_count));

        l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                                    HWAS::SRCI_PRIORITY_LOW);

        errlCommit( l_errl, RUNTIME_COMP_ID );
    }

    // Only call the HWP if 0-->1 or 1-->0
    if( ((l_count==0) &&  i_enable) ||
        ((l_count==1) && !i_enable) )
    {
        // NOTE Regarding the entity type passed to the HWP:
        // There are 3 independent registers used to trigger a
        // special wakeup (FSP,HOST,OCC), we are using the FSP
        // bit because HOST/OCC are already in use.

        p9specialWakeup::PROC_SPCWKUP_OPS l_spcwkupType;
        p9specialWakeup::PROC_SPCWKUP_ENTITY l_spcwkupSrc;
        if(! INITSERVICE::spBaseServicesEnabled())
        {
            l_spcwkupSrc = p9specialWakeup::FSP;
        }
        else
        {
            l_spcwkupSrc = p9specialWakeup::HOST;
        }

        if(i_enable)
        {
            l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE;
        }
        else
        {
            l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE;
        }

        if(l_type == TARGETING::TYPE_EQ)
        {
            fapi2::Target<fapi2::TARGET_TYPE_EQ>
                l_fapi_target(const_cast<TARGETING::Target*>(i_target));

            FAPI_EXEC_HWP(l_rc,
                          p9_cpu_special_wakeup_eq,
                          l_fapi_target,
                          l_spcwkupType,
                          l_spcwkupSrc );
            l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
        }
        else if(l_type == TARGETING::TYPE_EX)
        {
            fapi2::Target<fapi2::TARGET_TYPE_EX_CHIPLET>
                l_fapi_target(const_cast<TARGETING::Target*>(i_target));

            FAPI_EXEC_HWP(l_rc,
                          p9_cpu_special_wakeup_ex,
                          l_fapi_target,
                          l_spcwkupType,
                          l_spcwkupSrc );
            l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
        }
        else if(l_type == TARGETING::TYPE_CORE)
        {
            fapi2::Target<fapi2::TARGET_TYPE_CORE>
                l_fapi_target(const_cast<TARGETING::Target*>(i_target));

            FAPI_EXEC_HWP(l_rc,
                          p9_cpu_special_wakeup_core,
                          l_fapi_target,
                          l_spcwkupType,
                          l_spcwkupSrc );
            l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
        }

        if(l_errl)
        {
            TRACFCOMP( g_trac_scom,
                    "p9_cpu_special_wakeup ERROR :"
                    " Returning errorlog, reason=0x%x",
                    l_errl->reasonCode() );

            // Capture the target data in the elog
            ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl );
        }
    }

    // Update the counter
    if(!l_errl)
    {
        if(i_enable)
        {
            l_count++;
        }
        else
        {
            l_count--;
        }
        i_target->setAttr<ATTR_SPCWKUP_COUNT>(l_count);
    }

#endif // __HOSTBOOT_RUNTIME

    return l_errl;
}

}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2006 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file DiskImageResource.cc
///
/// An abstract base class referring to an image on disk.
///

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <vw/config.h>

#include <iostream>
#include <map>
#include <boost/algorithm/string.hpp>

#include <vw/FileIO/DiskImageResource.h>
#include <vw/FileIO/DiskImageResourcePDS.h>

#if defined(VW_HAVE_PKG_PNG) && VW_HAVE_PKG_PNG==1
#include <vw/FileIO/DiskImageResourcePNG.h>
#endif

#if defined(VW_HAVE_PKG_JPEG) && VW_HAVE_PKG_JPEG==1
#include <vw/FileIO/DiskImageResourceJPEG.h>
#endif

#if defined(VW_HAVE_PKG_TIFF) && VW_HAVE_PKG_TIFF==1
#include <vw/FileIO/DiskImageResourceTIFF.h>
#endif

#if defined(VW_HAVE_PKG_OPENEXR) && VW_HAVE_PKG_OPENEXR==1
#include <vw/FileIO/DiskImageResourceOpenEXR.h>
#endif

namespace {
  typedef std::map<std::string,vw::DiskImageResource::construct_open_func> OpenMapType;
  typedef std::map<std::string,vw::DiskImageResource::construct_create_func> CreateMapType;
  OpenMapType *open_map = 0;
  CreateMapType *create_map = 0;
}

void vw::DiskImageResource::register_file_type( std::string const& extension,
                                                vw::DiskImageResource::construct_open_func open_func,
                                                vw::DiskImageResource::construct_create_func create_func )
{
  if( ! open_map ) open_map = new OpenMapType();
  if( ! create_map ) create_map = new CreateMapType();
  open_map->insert( std::make_pair( extension, open_func ) );
  create_map->insert( std::make_pair( extension, create_func ) );
}

static std::string file_extension( std::string const& filename ) {
  std::string::size_type dot = filename.find_last_of('.');
  if (dot != std::string::npos) {
    std::string extension = filename.substr( dot );
    boost::to_lower( extension );
    return extension;
  } else {
    throw vw::IOErr() << "DiskImageResource: Cannot infer file format from filename with no file extension.";
  }
}

static void register_default_file_types() {
  static bool already = false;
  if( already ) return;
  already = true;
  vw::DiskImageResource::register_file_type( ".img", &vw::DiskImageResourcePDS::construct_open, &vw::DiskImageResourcePDS::construct_create );
#if defined(VW_HAVE_PKG_PNG) && VW_HAVE_PKG_PNG==1
  vw::DiskImageResource::register_file_type( ".png", &vw::DiskImageResourcePNG::construct_open, &vw::DiskImageResourcePNG::construct_create );
#endif
#if defined(VW_HAVE_PKG_JPEG) && VW_HAVE_PKG_JPEG==1
  vw::DiskImageResource::register_file_type( ".jpg", &vw::DiskImageResourceJPEG::construct_open, &vw::DiskImageResourceJPEG::construct_create );
  vw::DiskImageResource::register_file_type( ".jpeg", &vw::DiskImageResourceJPEG::construct_open, &vw::DiskImageResourceJPEG::construct_create );
#endif
#if defined(VW_HAVE_PKG_TIFF) && VW_HAVE_PKG_TIFF==1
  vw::DiskImageResource::register_file_type( ".tif", &vw::DiskImageResourceTIFF::construct_open, &vw::DiskImageResourceTIFF::construct_create );
  vw::DiskImageResource::register_file_type( ".tiff", &vw::DiskImageResourceTIFF::construct_open, &vw::DiskImageResourceTIFF::construct_create );
#endif
#if defined(VW_HAVE_PKG_OPENEXR) && VW_HAVE_PKG_OPENEXR==1
  vw::DiskImageResource::register_file_type( ".exr", &vw::DiskImageResourceOpenEXR::construct_open, &vw::DiskImageResourceOpenEXR::construct_create );
#endif
}

vw::DiskImageResource* vw::DiskImageResource::open( std::string const& filename ) {
  register_default_file_types();
  if( open_map ) {
    OpenMapType::const_iterator i = open_map->find( file_extension( filename ) );
    if( i != open_map->end() ) return i->second( filename );
  }
  throw NoImplErr() << "Unsuppported file format: " << filename;
}

vw::DiskImageResource* vw::DiskImageResource::create( std::string const& filename, GenericImageFormat const& format ) {
  register_default_file_types();
  if( create_map ) {
    CreateMapType::const_iterator i = create_map->find( file_extension( filename ) );
    if( i != create_map->end() ) return i->second( filename, format );
  }
  throw NoImplErr() << "Unsuppported file format: " << filename;
}
<commit_msg>Added include for DDD image header, and registered file type ".ddd".<commit_after>// __BEGIN_LICENSE__
//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2006 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file DiskImageResource.cc
///
/// An abstract base class referring to an image on disk.
///

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <vw/config.h>

#include <iostream>
#include <map>
#include <boost/algorithm/string.hpp>

#include <vw/FileIO/DiskImageResource.h>
#include <vw/FileIO/DiskImageResourcePDS.h>
#include <vw/FileIO/DiskImageResourceDDD.h>

#if defined(VW_HAVE_PKG_PNG) && VW_HAVE_PKG_PNG==1
#include <vw/FileIO/DiskImageResourcePNG.h>
#endif

#if defined(VW_HAVE_PKG_JPEG) && VW_HAVE_PKG_JPEG==1
#include <vw/FileIO/DiskImageResourceJPEG.h>
#endif

#if defined(VW_HAVE_PKG_TIFF) && VW_HAVE_PKG_TIFF==1
#include <vw/FileIO/DiskImageResourceTIFF.h>
#endif

#if defined(VW_HAVE_PKG_OPENEXR) && VW_HAVE_PKG_OPENEXR==1
#include <vw/FileIO/DiskImageResourceOpenEXR.h>
#endif

namespace {
  typedef std::map<std::string,vw::DiskImageResource::construct_open_func> OpenMapType;
  typedef std::map<std::string,vw::DiskImageResource::construct_create_func> CreateMapType;
  OpenMapType *open_map = 0;
  CreateMapType *create_map = 0;
}

void vw::DiskImageResource::register_file_type( std::string const& extension,
                                                vw::DiskImageResource::construct_open_func open_func,
                                                vw::DiskImageResource::construct_create_func create_func )
{
  if( ! open_map ) open_map = new OpenMapType();
  if( ! create_map ) create_map = new CreateMapType();
  open_map->insert( std::make_pair( extension, open_func ) );
  create_map->insert( std::make_pair( extension, create_func ) );
}

static std::string file_extension( std::string const& filename ) {
  std::string::size_type dot = filename.find_last_of('.');
  if (dot != std::string::npos) {
    std::string extension = filename.substr( dot );
    boost::to_lower( extension );
    return extension;
  } else {
    throw vw::IOErr() << "DiskImageResource: Cannot infer file format from filename with no file extension.";
  }
}

static void register_default_file_types() {
  static bool already = false;
  if( already ) return;
  already = true;
  vw::DiskImageResource::register_file_type( ".img", &vw::DiskImageResourcePDS::construct_open, &vw::DiskImageResourcePDS::construct_create );

  vw::DiskImageResource::register_file_type( ".ddd", &vw::DiskImageResourceDDD::construct_open, &vw::DiskImageResourceDDD::construct_create );

#if defined(VW_HAVE_PKG_PNG) && VW_HAVE_PKG_PNG==1
  vw::DiskImageResource::register_file_type( ".png", &vw::DiskImageResourcePNG::construct_open, &vw::DiskImageResourcePNG::construct_create );
#endif
#if defined(VW_HAVE_PKG_JPEG) && VW_HAVE_PKG_JPEG==1
  vw::DiskImageResource::register_file_type( ".jpg", &vw::DiskImageResourceJPEG::construct_open, &vw::DiskImageResourceJPEG::construct_create );
  vw::DiskImageResource::register_file_type( ".jpeg", &vw::DiskImageResourceJPEG::construct_open, &vw::DiskImageResourceJPEG::construct_create );
#endif
#if defined(VW_HAVE_PKG_TIFF) && VW_HAVE_PKG_TIFF==1
  vw::DiskImageResource::register_file_type( ".tif", &vw::DiskImageResourceTIFF::construct_open, &vw::DiskImageResourceTIFF::construct_create );
  vw::DiskImageResource::register_file_type( ".tiff", &vw::DiskImageResourceTIFF::construct_open, &vw::DiskImageResourceTIFF::construct_create );
#endif
#if defined(VW_HAVE_PKG_OPENEXR) && VW_HAVE_PKG_OPENEXR==1
  vw::DiskImageResource::register_file_type( ".exr", &vw::DiskImageResourceOpenEXR::construct_open, &vw::DiskImageResourceOpenEXR::construct_create );
#endif
}

vw::DiskImageResource* vw::DiskImageResource::open( std::string const& filename ) {
  register_default_file_types();
  if( open_map ) {
    OpenMapType::const_iterator i = open_map->find( file_extension( filename ) );
    if( i != open_map->end() ) return i->second( filename );
  }
  throw NoImplErr() << "Unsuppported file format: " << filename;
}

vw::DiskImageResource* vw::DiskImageResource::create( std::string const& filename, GenericImageFormat const& format ) {
  register_default_file_types();
  if( create_map ) {
    CreateMapType::const_iterator i = create_map->find( file_extension( filename ) );
    if( i != create_map->end() ) return i->second( filename, format );
  }
  throw NoImplErr() << "Unsuppported file format: " << filename;
}
<|endoftext|>


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

#include "client_win.h"
#include "cefclient/util.h"

//#include "Capture.h"

#include <Winuser.h>

Client_Win::Client_Win()
  :INIT_LOGGER(Client_Win)
{

}

Client_Win::~Client_Win()
{

}

bool Client_Win::OnKeyEvent( CefRefPtr<CefBrowser> browser, const CefKeyEvent& event, CefEventHandle os_event )
{
  // see chrome shortcuts: https://support.google.com/chrome/topic/25799?hl=en
  // see windows key codes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
  REQUIRE_UI_THREAD();
  LOG_TRACE(logger())
    << "OnKeyEvent, type=" << event.type
    << " modifiers=" << event.modifiers
    << " windows_key_code=" << event.windows_key_code
    << " unmodified_character=" << event.unmodified_character;

  if(!event.focus_on_editable_field && event.type == KEYEVENT_RAWKEYDOWN) // shortcut only on non edit field
  {
    if(event.modifiers == EVENTFLAG_NONE) // modifiers: none
    {
      switch (event.windows_key_code)
      {

        case VK_F5:
        {
          browser->Reload();
          return true;
        }
        case VK_F11:
        {
            // GC: Wait
			// toggleFullScreen(browser->GetHost()->GetWindowHandle(), true);

		  // FM: Also show dev tools when exiting full screen for debugging purposes
		  showDevTools(browser);
          return true;
        }
        default:
          break;
      }
    }
    if(event.modifiers & EVENTFLAG_CONTROL_DOWN) // modifiers: CTRL
    {
      switch (event.windows_key_code)
      {
        case VK_F5:
        case 0x52: // R - Key
        {
          browser->ReloadIgnoreCache();
          return true;
        }
        default:
          break;
      }
    }
    if(event.modifiers & EVENTFLAG_SHIFT_DOWN) // modifiers: SHIFT
    {
      switch (event.windows_key_code)
      {
      case VK_F5:
      {
        browser->ReloadIgnoreCache();
        return true;
      }
      default:
        break;
      }
    }
    if( (event.modifiers & EVENTFLAG_SHIFT_DOWN) && (event.modifiers & EVENTFLAG_CONTROL_DOWN) ) // modifiers: SHIFT + CTRL
    {
      switch (event.windows_key_code)
      {
        case 0x49: // I - Key
        {
          showDevTools(browser);
          return true;
        }
        default:
          break;
      }
    }
  }

  return false;
}

void Client_Win::toggleFullScreen(CefWindowHandle window, bool visible)
{
  LONG visibleFlag = (visible ? WS_VISIBLE : 0);
  window = GetParent(window);
  // Save current window state if not already fullscreen.
  if(!_bIsFullScreen)
  {
    _savedWindowInfo.maximized = ::IsZoomed(window);
    if(_savedWindowInfo.maximized)
      ::SendMessage(window, WM_SYSCOMMAND, SC_RESTORE, 0);
    _savedWindowInfo.style = GetWindowLong(window, GWL_STYLE);
    _savedWindowInfo.ex_style = GetWindowLong(window, GWL_EXSTYLE);
    GetWindowRect(window, &_savedWindowInfo.rect);
  }

  _bIsFullScreen =! _bIsFullScreen; // toggle
  if(_bIsFullScreen)
  {
    SetWindowLong(window, GWL_STYLE,
                  _savedWindowInfo.style & ~(WS_CAPTION | WS_THICKFRAME) | visibleFlag);
    SetWindowLong(window, GWL_EXSTYLE,
                  _savedWindowInfo.ex_style & ~(WS_EX_DLGMODALFRAME |
                  WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE) | visibleFlag);

    MONITORINFO monitor_info;
    monitor_info.cbSize = sizeof(monitor_info);
    GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST),
                                     &monitor_info);
    SetWindowPos(window, NULL,
                 monitor_info.rcMonitor.left,
                 monitor_info.rcMonitor.top,
                 monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
                 monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
                 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  }
  else
  {
    SetWindowLong(window, GWL_STYLE, _savedWindowInfo.style | visibleFlag);
    SetWindowLong(window, GWL_EXSTYLE, _savedWindowInfo.ex_style | visibleFlag);

    SetWindowPos(window, NULL,
      _savedWindowInfo.rect.left,
      _savedWindowInfo.rect.top,
      _savedWindowInfo.rect.right - _savedWindowInfo.rect.left,
      _savedWindowInfo.rect.bottom - _savedWindowInfo.rect.top,
      SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);

    if (_savedWindowInfo.maximized)
      ::SendMessage(window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  }
}

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

#include "client_win.h"
#include "cefclient/util.h"

#include <Winuser.h>

Client_Win::Client_Win()
  :INIT_LOGGER(Client_Win)
{

}

Client_Win::~Client_Win()
{

}

bool Client_Win::OnKeyEvent( CefRefPtr<CefBrowser> browser, const CefKeyEvent& event, CefEventHandle os_event )
{
  // see chrome shortcuts: https://support.google.com/chrome/topic/25799?hl=en
  // see windows key codes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
  REQUIRE_UI_THREAD();
  LOG_TRACE(logger())
    << "OnKeyEvent, type=" << event.type
    << " modifiers=" << event.modifiers
    << " windows_key_code=" << event.windows_key_code
    << " unmodified_character=" << event.unmodified_character;

  if(!event.focus_on_editable_field && event.type == KEYEVENT_RAWKEYDOWN) // shortcut only on non edit field
  {
    if(event.modifiers == EVENTFLAG_NONE) // modifiers: none
    {
      switch (event.windows_key_code)
      {

        case VK_F5:
        {
          browser->Reload();
          return true;
        }
        case VK_F11:
        {
            // GC: Wait
			// toggleFullScreen(browser->GetHost()->GetWindowHandle(), true);

		  // FM: Also show dev tools when exiting full screen for debugging purposes
		  showDevTools(browser);
          return true;
        }
        default:
          break;
      }
    }
    if(event.modifiers & EVENTFLAG_CONTROL_DOWN) // modifiers: CTRL
    {
      switch (event.windows_key_code)
      {
        case VK_F5:
        case 0x52: // R - Key
        {
          browser->ReloadIgnoreCache();
          return true;
        }
        default:
          break;
      }
    }
    if(event.modifiers & EVENTFLAG_SHIFT_DOWN) // modifiers: SHIFT
    {
      switch (event.windows_key_code)
      {
      case VK_F5:
      {
        browser->ReloadIgnoreCache();
        return true;
      }
      default:
        break;
      }
    }
    if( (event.modifiers & EVENTFLAG_SHIFT_DOWN) && (event.modifiers & EVENTFLAG_CONTROL_DOWN) ) // modifiers: SHIFT + CTRL
    {
      switch (event.windows_key_code)
      {
        case 0x49: // I - Key
        {
          showDevTools(browser);
          return true;
        }
        default:
          break;
      }
    }
  }

  return false;
}

void Client_Win::toggleFullScreen(CefWindowHandle window, bool visible)
{
  LONG visibleFlag = (visible ? WS_VISIBLE : 0);
  window = GetParent(window);
  // Save current window state if not already fullscreen.
  if(!_bIsFullScreen)
  {
    _savedWindowInfo.maximized = ::IsZoomed(window);
    if(_savedWindowInfo.maximized)
      ::SendMessage(window, WM_SYSCOMMAND, SC_RESTORE, 0);
    _savedWindowInfo.style = GetWindowLong(window, GWL_STYLE);
    _savedWindowInfo.ex_style = GetWindowLong(window, GWL_EXSTYLE);
    GetWindowRect(window, &_savedWindowInfo.rect);
  }

  _bIsFullScreen =! _bIsFullScreen; // toggle
  if(_bIsFullScreen)
  {
    SetWindowLong(window, GWL_STYLE,
                  _savedWindowInfo.style & ~(WS_CAPTION | WS_THICKFRAME) | visibleFlag);
    SetWindowLong(window, GWL_EXSTYLE,
                  _savedWindowInfo.ex_style & ~(WS_EX_DLGMODALFRAME |
                  WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE) | visibleFlag);

    MONITORINFO monitor_info;
    monitor_info.cbSize = sizeof(monitor_info);
    GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST),
                                     &monitor_info);
    SetWindowPos(window, NULL,
                 monitor_info.rcMonitor.left,
                 monitor_info.rcMonitor.top,
                 monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
                 monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
                 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  }
  else
  {
    SetWindowLong(window, GWL_STYLE, _savedWindowInfo.style | visibleFlag);
    SetWindowLong(window, GWL_EXSTYLE, _savedWindowInfo.ex_style | visibleFlag);

    SetWindowPos(window, NULL,
      _savedWindowInfo.rect.left,
      _savedWindowInfo.rect.top,
      _savedWindowInfo.rect.right - _savedWindowInfo.rect.left,
      _savedWindowInfo.rect.bottom - _savedWindowInfo.rect.top,
      SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);

    if (_savedWindowInfo.maximized)
      ::SendMessage(window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  }
}

<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2020 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/platform_android.h"

#include <android/configuration.h>
#include <dlfcn.h>

#include "xenia/base/assert.h"

namespace xe {
namespace platform {
namespace android {

static bool initialized = false;

static int32_t api_level_ = __ANDROID_API__;

static ApiFunctions api_functions_;

void Initialize(const ANativeActivity* activity) {
  if (initialized) {
    return;
  }

  AConfiguration* configuration = AConfiguration_new();
  AConfiguration_fromAssetManager(configuration, activity->assetManager);
  api_level_ = AConfiguration_getSdkVersion(configuration);
  AConfiguration_delete(configuration);

  if (api_level_ >= 26) {
    // Leaked intentionally as these will be usable anywhere, already loaded
    // into the address space as the application is linked against them.
    // https://chromium.googlesource.com/chromium/src/+/master/third_party/ashmem/ashmem-dev.c#201
    void* libandroid = dlopen("libandroid.so", RTLD_NOW);
    assert_not_null(libandroid);
    void* libc = dlopen("libc.so", RTLD_NOW);
    assert_not_null(libc);
#define XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(lib, name, api)    \
  api_functions_.api_##api.name =                                \
      reinterpret_cast<decltype(api_functions_.api_##api.name)>( \
          dlsym(lib, #name));                                    \
  assert_not_null(api_functions_.api_##api.name);
    XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(libandroid, ASharedMemory_create, 26);
    XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(libc, pthread_getname_np, 26);
#undef XE_PLATFORM_ANDROID_LOAD_API_FUNCTION
  }

  initialized = true;
}

int32_t api_level() { return api_level_; }

const ApiFunctions& api_functions() { return api_functions_; }

}  // namespace android
}  // namespace platform
}  // namespace xe
<commit_msg>[Android] Add a comment about pthreads dynamic loading<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2020 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/platform_android.h"

#include <android/configuration.h>
#include <dlfcn.h>

#include "xenia/base/assert.h"

namespace xe {
namespace platform {
namespace android {

static bool initialized = false;

static int32_t api_level_ = __ANDROID_API__;

static ApiFunctions api_functions_;

void Initialize(const ANativeActivity* activity) {
  if (initialized) {
    return;
  }

  AConfiguration* configuration = AConfiguration_new();
  AConfiguration_fromAssetManager(configuration, activity->assetManager);
  api_level_ = AConfiguration_getSdkVersion(configuration);
  AConfiguration_delete(configuration);

  if (api_level_ >= 26) {
    // Leaked intentionally as these will be usable anywhere, already loaded
    // into the address space as the application is linked against them.
    // https://chromium.googlesource.com/chromium/src/+/master/third_party/ashmem/ashmem-dev.c#201
    void* libandroid = dlopen("libandroid.so", RTLD_NOW);
    assert_not_null(libandroid);
    void* libc = dlopen("libc.so", RTLD_NOW);
    assert_not_null(libc);
#define XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(lib, name, api)    \
  api_functions_.api_##api.name =                                \
      reinterpret_cast<decltype(api_functions_.api_##api.name)>( \
          dlsym(lib, #name));                                    \
  assert_not_null(api_functions_.api_##api.name);
    XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(libandroid, ASharedMemory_create, 26);
    // pthreads are a part of Bionic libc on Android.
    XE_PLATFORM_ANDROID_LOAD_API_FUNCTION(libc, pthread_getname_np, 26);
#undef XE_PLATFORM_ANDROID_LOAD_API_FUNCTION
  }

  initialized = true;
}

int32_t api_level() { return api_level_; }

const ApiFunctions& api_functions() { return api_functions_; }

}  // namespace android
}  // namespace platform
}  // namespace xe
<|endoftext|>


<commit_before>//  Copyright 2011 Gregory Szorc
//
//  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 <zippylog/envelope.hpp>
#include <zippylog/protocol/request.pb.h>

#include <gtest/gtest.h>
#include <string.h>

using ::std::invalid_argument;
using ::std::string;
using ::zippylog::Envelope;
using ::zippylog::protocol::request::GetStreamSegmentV1;
using ::zippylog::protocol::request::PingV1;
using ::zmq::message_t;

namespace zippylog {

TEST(EnvelopeTest, ConstructorEmptyEnvelope)
{
    ASSERT_NO_THROW(Envelope e());

    Envelope e;
    EXPECT_EQ(0, e.MessageCount());
    string s;
    EXPECT_TRUE(e.Serialize(s));
}

TEST(EnvelopeTest, ConstructorInvalidData)
{
    ASSERT_THROW(Envelope e(NULL, 0), invalid_argument);
    ASSERT_THROW(Envelope e(NULL, 10), invalid_argument);
    ASSERT_THROW(Envelope e((void *)324234, 0), invalid_argument);
    ASSERT_THROW(Envelope e((void *)352537, -10), invalid_argument);
}

TEST(EnvelopeTest, ConstructorZmqMessage)
{
    message_t m;

    // empty message
    EXPECT_THROW(Envelope e(m), invalid_argument);

    // offset >= size
    m.rebuild(10);
    EXPECT_THROW(Envelope e(m, 9), invalid_argument);

    Envelope e;
    ASSERT_TRUE(e.ToZmqMessage(m));
    EXPECT_NO_THROW(Envelope e2(m));

    message_t m2(m.size() + 1);
    memset(m.data(), 1, 1);
    memcpy((void *)((char *)m2.data() + 1), m.data(), m.size());
    EXPECT_NO_THROW(Envelope e2(m2, 1));
}

TEST(EnvelopeTest, ConstructorString)
{
    EXPECT_NO_THROW(Envelope e("hello, world"));

    Envelope e("hello, world");
    EXPECT_EQ("hello, world", e.GetStringValueField());
}

TEST(EnvelopeTest, EquivalenceAndCopying)
{
    Envelope e1("hello, world");

    Envelope e2(e1);
    Envelope e3 = e1;

    EXPECT_TRUE(e1 == e2);
    EXPECT_TRUE(e1 == e3);
    EXPECT_TRUE(e2 == e3);

    Envelope e4;
    EXPECT_TRUE(e1 != e4);
}

TEST(EnvelopeTest, Serialize)
{
    Envelope e;
    string s;
    ASSERT_TRUE(e.Serialize(s));

    string s2 = "foo";
    ASSERT_TRUE(e.Serialize(s2));
    ASSERT_EQ(3 + s.length(), s2.length());
}

TEST(EnvelopeTest, ZMQSerialization)
{
    Envelope e;

    string expected;
    ASSERT_TRUE(e.Serialize(expected));
    message_t m;

    ASSERT_TRUE(e.ToZmqMessage(m));
    ASSERT_EQ(expected.length(), m.size());
    EXPECT_TRUE(0 == memcmp(m.data(), expected.data(), m.size()));
}

TEST(EnvelopeTest, ZMQProtocolSerialization)
{
    Envelope e;

    string expected(1, 0x01);
    ASSERT_TRUE(e.Serialize(expected));
    message_t m;
    ASSERT_TRUE(e.ToProtocolZmqMessage(m));
    ASSERT_EQ(expected.length(), m.size());
    EXPECT_EQ(0x01, *((char *)m.data()));
    EXPECT_TRUE(0 == memcmp(m.data(), expected.data(), m.size()));
}

TEST(EnvelopeTest, GetMessageErrors)
{
    Envelope e;

    EXPECT_THROW(e.GetMessage(-1), invalid_argument);
    EXPECT_TRUE(NULL == e.GetMessage(0));
    EXPECT_TRUE(NULL == e.GetMessage(10));
}

TEST(EnvelopeTest, UnknownMessageTypes)
{
    Envelope e;
    e.envelope.add_message("foo bar");
    e.envelope.add_message_namespace(32423432);
    e.envelope.add_message_type(89672356);

    string serialized;
    EXPECT_TRUE(e.Serialize(serialized));

    Envelope e2(serialized.data(), serialized.length());
    EXPECT_EQ(1, e2.MessageCount());
    EXPECT_TRUE(NULL == e2.GetMessage(0));
}

TEST(EnvelopeTest, MessageSemantics)
{
    Envelope e;
    GetStreamSegmentV1 get_stream;
    get_stream.set_path("/");
    get_stream.set_start_offset(0);
    get_stream.add_to_envelope(e);

    uint32 expected_namespace = GetStreamSegmentV1::zippylog_namespace;
    uint32 expected_type = GetStreamSegmentV1::zippylog_enumeration;

    EXPECT_EQ(1, e.MessageCount());
    EXPECT_EQ(expected_namespace, e.MessageNamespace(0));
    EXPECT_EQ(expected_type, e.MessageType(0));

    GetStreamSegmentV1 *message = (GetStreamSegmentV1 *)e.GetMessage(0);
    ASSERT_TRUE(NULL != message);

    // verify the pointer is the same
    GetStreamSegmentV1 *message2 = (GetStreamSegmentV1 *)e.GetMessage(0);
    EXPECT_EQ(message, message2);

    // verify change in original doesn't touch what's in envelope
    get_stream.set_start_offset(100);
    EXPECT_EQ(0, message->start_offset());
}

TEST(EnvelopeTest, MessagesAndCopying)
{
    Envelope e1;
    PingV1 p1;
    p1.add_to_envelope(e1);

    EXPECT_TRUE(NULL != e1.GetMessage(0));

    Envelope e2 = e1;
    EXPECT_EQ(1, e2.MessageCount());
    PingV1 *p2 = (PingV1 *)e2.GetMessage(0);
    ASSERT_TRUE(NULL != p2);
    EXPECT_TRUE(&p1 != p2);
}

} // namespace
<commit_msg>convert to test fixture; test random functions<commit_after>//  Copyright 2011 Gregory Szorc
//
//  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 <zippylog/testing.hpp>

#include <zippylog/envelope.hpp>
#include <zippylog/protocol/request.pb.h>

#include <gtest/gtest.h>
#include <string>
#include <utility>
#include <vector>

using ::std::invalid_argument;
using ::std::pair;
using ::std::string;
using ::std::vector;
using ::zippylog::Envelope;
using ::zippylog::protocol::request::GetStreamSegmentV1;
using ::zippylog::protocol::request::PingV1;
using ::zmq::message_t;

namespace zippylog {

class EnvelopeTest : public ::zippylog::testing::TestBase
{ };

TEST_F(EnvelopeTest, ConstructorEmptyEnvelope)
{
    ASSERT_NO_THROW(Envelope e());

    Envelope e;
    EXPECT_EQ(0, e.MessageCount());
    string s;
    EXPECT_TRUE(e.Serialize(s));
}

TEST_F(EnvelopeTest, ConstructorInvalidData)
{
    ASSERT_THROW(Envelope e(NULL, 0), invalid_argument);
    ASSERT_THROW(Envelope e(NULL, 10), invalid_argument);
    ASSERT_THROW(Envelope e((void *)324234, 0), invalid_argument);
    ASSERT_THROW(Envelope e((void *)352537, -10), invalid_argument);
}

TEST_F(EnvelopeTest, ConstructorZmqMessage)
{
    message_t m;

    // empty message
    EXPECT_THROW(Envelope e(m), invalid_argument);

    // offset >= size
    m.rebuild(10);
    EXPECT_THROW(Envelope e(m, 9), invalid_argument);

    Envelope e;
    ASSERT_TRUE(e.ToZmqMessage(m));
    EXPECT_NO_THROW(Envelope e2(m));

    message_t m2(m.size() + 1);
    memset(m.data(), 1, 1);
    memcpy((void *)((char *)m2.data() + 1), m.data(), m.size());
    EXPECT_NO_THROW(Envelope e2(m2, 1));
}

TEST_F(EnvelopeTest, ConstructorString)
{
    EXPECT_NO_THROW(Envelope e("hello, world"));

    Envelope e("hello, world");
    EXPECT_EQ("hello, world", e.GetStringValueField());
}

TEST_F(EnvelopeTest, EquivalenceAndCopying)
{
    Envelope e1("hello, world");

    Envelope e2(e1);
    Envelope e3 = e1;

    EXPECT_TRUE(e1 == e2);
    EXPECT_TRUE(e1 == e3);
    EXPECT_TRUE(e2 == e3);

    Envelope e4;
    EXPECT_TRUE(e1 != e4);
}

TEST_F(EnvelopeTest, Serialize)
{
    Envelope e;
    string s;
    ASSERT_TRUE(e.Serialize(s));

    string s2 = "foo";
    ASSERT_TRUE(e.Serialize(s2));
    ASSERT_EQ(3 + s.length(), s2.length());
}

TEST_F(EnvelopeTest, ZMQSerialization)
{
    Envelope e;

    string expected;
    ASSERT_TRUE(e.Serialize(expected));
    message_t m;

    ASSERT_TRUE(e.ToZmqMessage(m));
    ASSERT_EQ(expected.length(), m.size());
    EXPECT_TRUE(0 == memcmp(m.data(), expected.data(), m.size()));
}

TEST_F(EnvelopeTest, ZMQProtocolSerialization)
{
    Envelope e;

    string expected(1, 0x01);
    ASSERT_TRUE(e.Serialize(expected));
    message_t m;
    ASSERT_TRUE(e.ToProtocolZmqMessage(m));
    ASSERT_EQ(expected.length(), m.size());
    EXPECT_EQ(0x01, *((char *)m.data()));
    EXPECT_TRUE(0 == memcmp(m.data(), expected.data(), m.size()));
}

TEST_F(EnvelopeTest, GetMessageErrors)
{
    Envelope e;

    EXPECT_THROW(e.GetMessage(-1), invalid_argument);
    EXPECT_TRUE(NULL == e.GetMessage(0));
    EXPECT_TRUE(NULL == e.GetMessage(10));
}

TEST_F(EnvelopeTest, UnknownMessageTypes)
{
    Envelope e;
    e.envelope.add_message("foo bar");
    e.envelope.add_message_namespace(32423432);
    e.envelope.add_message_type(89672356);

    string serialized;
    EXPECT_TRUE(e.Serialize(serialized));

    Envelope e2(serialized.data(), serialized.length());
    EXPECT_EQ(1, e2.MessageCount());
    EXPECT_TRUE(NULL == e2.GetMessage(0));
}

TEST_F(EnvelopeTest, MessageSemantics)
{
    Envelope e;
    GetStreamSegmentV1 get_stream;
    get_stream.set_path("/");
    get_stream.set_start_offset(0);
    get_stream.add_to_envelope(e);

    uint32 expected_namespace = GetStreamSegmentV1::zippylog_namespace;
    uint32 expected_type = GetStreamSegmentV1::zippylog_enumeration;

    EXPECT_EQ(1, e.MessageCount());
    EXPECT_EQ(expected_namespace, e.MessageNamespace(0));
    EXPECT_EQ(expected_type, e.MessageType(0));

    GetStreamSegmentV1 *message = (GetStreamSegmentV1 *)e.GetMessage(0);
    ASSERT_TRUE(NULL != message);

    // verify the pointer is the same
    GetStreamSegmentV1 *message2 = (GetStreamSegmentV1 *)e.GetMessage(0);
    EXPECT_EQ(message, message2);

    // verify change in original doesn't touch what's in envelope
    get_stream.set_start_offset(100);
    EXPECT_EQ(0, message->start_offset());
}

TEST_F(EnvelopeTest, MessagesAndCopying)
{
    Envelope e1;
    PingV1 p1;
    p1.add_to_envelope(e1);

    EXPECT_TRUE(NULL != e1.GetMessage(0));

    Envelope e2 = e1;
    EXPECT_EQ(1, e2.MessageCount());
    PingV1 *p2 = (PingV1 *)e2.GetMessage(0);
    ASSERT_TRUE(NULL != p2);
    EXPECT_TRUE(&p1 != p2);
}

TEST_F(EnvelopeTest, RandomGeneration)
{
    vector< pair<uint32, uint32> > enumerations;
    MessageRegistrar::instance()->GetAllEnumerations(enumerations);

    vector < pair<uint32, uint32> >::iterator i = enumerations.begin();
    for (; i != enumerations.end(); i++) {
        for (int32 j = 10; j; j--) {
            ::google::protobuf::Message *m = this->GetRandomMessage(i->first, i->second);
            delete m;
        }
    }

    for (int32 j = 1000; j; j--) {
        this->GetRandomEnvelope();
    }
}

} // namespace
<|endoftext|>


<commit_before>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh is free software: you can redistribute it and/or modify         *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                              *
 *   $Date$                                                                  *
 *                                                                           *
\*===========================================================================*/

#ifndef PROPERTYMANAGER_HH_
#define PROPERTYMANAGER_HH_

#include <sstream>

namespace OpenMesh {

/**
 * This class is intended to manage the lifecycle of properties.
 * It also defines convenience operators to access the encapsulated
 * property's value.
 *
 * Usage example:
 *
 * \code
 * TriMesh mesh;
 * PropertyManager<VPropHandleT<bool>, MeshT> visited(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de");
 *
 * for (TriMesh::VertexIter vh_it = mesh.begin(); ... ; ...) {
 *     if (!visited[*vh_it]) {
 *         visitComponent(mesh, *vh_it, visited);
 *     }
 * }
 * \endcode
 *
 */
template<typename PROPTYPE, typename MeshT>
class PropertyManager {
    private:
        /**
         * Noncopyable because there aren't not straightforward copy semantics.
         */
        PropertyManager(const PropertyManager&);

        /**
         * Noncopyable because there aren't not straightforward copy semantics.
         */
        const PropertyManager& operator=(const PropertyManager&);

    public:
        /**
         * Constructor.
         *
         * Throws an \p std::runtime_error if \p existing is true and
         * no property named \p propname of the appropriate property type
         * exists.
         *
         * @param mesh The mesh on which to create the property.
         * @param propname The name of the property.
         * @param existing If false, a new property is created and its lifecycle is managed (i.e.
         * the property is deleted upon destruction of the PropertyManager instance). If true,
         * the instance merely acts as a convenience wrapper around an existing property with no
         * lifecycle management whatsoever.
         */
        PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing) {
            if (existing) {
                if (!mesh_->get_property_handle(prop_, propname)) {
                    std::ostringstream oss;
                    oss << "Requested property handle \"" << propname << "\" does not exist.";
                    throw std::runtime_error(oss.str());
                }
            } else {
                mesh_->add_property(prop_, propname);
            }
        }

        ~PropertyManager() {
            deleteProperty();
        }

#if __cplusplus > 199711L or __GXX_EXPERIMENTAL_CXX0X__
        /**
         * Move constructor. Transfers ownership (delete responsibility).
         */
        PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_) {
            rhs.retain_ = true;
        }

        /**
         * Move assignment. Transfers ownership (delete responsibility).
         */
        PropertyManager &operator=(PropertyManager &&rhs) {

            deleteProperty();

            mesh_ = rhs.mesh_;
            prop_ = rhs.prop_;
            retain_ = rhs.retain_;
            rhs.retain_ = true;

            return *this;
        }

        /**
         * Create a property manager for the supplied property and mesh.
         * If the property doesn't exist, it is created. In any case,
         * lifecycle management is disabled.
         */
        static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) {
            PROPTYPE dummy_prop;
            PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname));
            pm.retain();
            return std::move(pm);
        }
#endif

        /**
         * \brief Disable lifecycle management for this property.
         *
         * If this method is called, the encapsulated property will not be deleted
         * upon destruction of the PropertyManager instance.
         */
        inline void retain() {
            retain_ = true;
        }

        /**
         * Access the encapsulated property.
         */
        inline PROPTYPE &operator* () {
            return prop_;
        }

        /**
         * Access the encapsulated property.
         */
        inline const PROPTYPE &operator* () const {
            return prop_;
        }

        /**
         * Enables convenient access to the encapsulated property.
         *
         * For a usage example see this class' documentation.
         *
         * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.)
         */
        template<typename HandleType>
        inline typename PROPTYPE::reference operator[] (const HandleType &handle) {
            return mesh_->property(prop_, handle);
        }

        /**
         * Enables convenient access to the encapsulated property.
         *
         * For a usage example see this class' documentation.
         *
         * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.)
         */
        template<typename HandleType>
        inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const {
            return mesh_->property(prop_, handle);
        }

    private:
        void deleteProperty() {
            if (!retain_)
                mesh_->remove_property(prop_);
        }

    private:
        MeshT *mesh_;
        PROPTYPE prop_;
        bool retain_;
};

} /* namespace OpenMesh */
#endif /* PROPERTYMANAGER_HH_ */
<commit_msg>OpenMesh/Core/Utils/PropertyManager: Added property to retain() method.<commit_after>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh is free software: you can redistribute it and/or modify         *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                              *
 *   $Date$                                                                  *
 *                                                                           *
\*===========================================================================*/

#ifndef PROPERTYMANAGER_HH_
#define PROPERTYMANAGER_HH_

#include <sstream>

namespace OpenMesh {

/**
 * This class is intended to manage the lifecycle of properties.
 * It also defines convenience operators to access the encapsulated
 * property's value.
 *
 * Usage example:
 *
 * \code
 * TriMesh mesh;
 * PropertyManager<VPropHandleT<bool>, MeshT> visited(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de");
 *
 * for (TriMesh::VertexIter vh_it = mesh.begin(); ... ; ...) {
 *     if (!visited[*vh_it]) {
 *         visitComponent(mesh, *vh_it, visited);
 *     }
 * }
 * \endcode
 *
 */
template<typename PROPTYPE, typename MeshT>
class PropertyManager {
    private:
        /**
         * Noncopyable because there aren't not straightforward copy semantics.
         */
        PropertyManager(const PropertyManager&);

        /**
         * Noncopyable because there aren't not straightforward copy semantics.
         */
        const PropertyManager& operator=(const PropertyManager&);

    public:
        /**
         * Constructor.
         *
         * Throws an \p std::runtime_error if \p existing is true and
         * no property named \p propname of the appropriate property type
         * exists.
         *
         * @param mesh The mesh on which to create the property.
         * @param propname The name of the property.
         * @param existing If false, a new property is created and its lifecycle is managed (i.e.
         * the property is deleted upon destruction of the PropertyManager instance). If true,
         * the instance merely acts as a convenience wrapper around an existing property with no
         * lifecycle management whatsoever.
         */
        PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing) {
            if (existing) {
                if (!mesh_->get_property_handle(prop_, propname)) {
                    std::ostringstream oss;
                    oss << "Requested property handle \"" << propname << "\" does not exist.";
                    throw std::runtime_error(oss.str());
                }
            } else {
                mesh_->add_property(prop_, propname);
            }
        }

        ~PropertyManager() {
            deleteProperty();
        }

#if __cplusplus > 199711L or __GXX_EXPERIMENTAL_CXX0X__
        /**
         * Move constructor. Transfers ownership (delete responsibility).
         */
        PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_) {
            rhs.retain_ = true;
        }

        /**
         * Move assignment. Transfers ownership (delete responsibility).
         */
        PropertyManager &operator=(PropertyManager &&rhs) {

            deleteProperty();

            mesh_ = rhs.mesh_;
            prop_ = rhs.prop_;
            retain_ = rhs.retain_;
            rhs.retain_ = true;

            return *this;
        }

        /**
         * Create a property manager for the supplied property and mesh.
         * If the property doesn't exist, it is created. In any case,
         * lifecycle management is disabled.
         */
        static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) {
            PROPTYPE dummy_prop;
            PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname));
            pm.retain();
            return std::move(pm);
        }
#endif

        /**
         * \brief Disable lifecycle management for this property.
         *
         * If this method is called, the encapsulated property will not be deleted
         * upon destruction of the PropertyManager instance.
         */
        inline void retain(bool doRetain = true) {
            retain_ = doRetain;
        }

        /**
         * Access the encapsulated property.
         */
        inline PROPTYPE &operator* () {
            return prop_;
        }

        /**
         * Access the encapsulated property.
         */
        inline const PROPTYPE &operator* () const {
            return prop_;
        }

        /**
         * Enables convenient access to the encapsulated property.
         *
         * For a usage example see this class' documentation.
         *
         * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.)
         */
        template<typename HandleType>
        inline typename PROPTYPE::reference operator[] (const HandleType &handle) {
            return mesh_->property(prop_, handle);
        }

        /**
         * Enables convenient access to the encapsulated property.
         *
         * For a usage example see this class' documentation.
         *
         * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.)
         */
        template<typename HandleType>
        inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const {
            return mesh_->property(prop_, handle);
        }

    private:
        void deleteProperty() {
            if (!retain_)
                mesh_->remove_property(prop_);
        }

    private:
        MeshT *mesh_;
        PROPTYPE prop_;
        bool retain_;
};

} /* namespace OpenMesh */
#endif /* PROPERTYMANAGER_HH_ */
<|endoftext|>


<commit_before><commit_msg>Refactoring ...<commit_after><|endoftext|>