<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/mbox/ipcSp.C $                                        */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2013,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 <mbox/ipc_msg_types.H>
#include "ipcSp.H"
#include <runtime/runtime.H>
#include <vfs/vfs.H>
#include <mbox/ipc_reasoncodes.H>
#include <mbox/mboxif.H>
#include <errl/errlmanager.H>
#include <mbox/mbox_reasoncodes.H>
#include <intr/interrupt.H>
#include <initservice/initserviceif.H>
#include <sbeio/sbeioif.H>
#include <util/utiltce.H>
#include <targeting/targplatutil.H>

namespace ISTEP_21
{
    extern errlHndl_t callShutdown ( uint64_t i_hbInstance,
                                     bool i_masterInstance,
                                     const uint64_t i_commBase );
};

trace_desc_t* g_trac_ipc = NULL;
TRAC_INIT(&g_trac_ipc, IPC_TRACE_NAME, KILOBYTE);

using namespace IPC;
using namespace ERRORLOG;

IpcSp::IpcSp()
    :
        iv_msgQ()
{
}

IpcSp::~IpcSp()
{
    msg_q_destroy(iv_msgQ);
}

void IpcSp::init(errlHndl_t & o_errl)
{
    o_errl = Singleton<IpcSp>::instance()._init();
}

void* IpcSp::msg_handler(void *unused)
{
    Singleton<IpcSp>::instance().msgHandler();
    return NULL;
}

errlHndl_t IpcSp::_init()
{
    errlHndl_t err = NULL;

    iv_msgQ = msg_q_create();
    err = MBOX::msgq_register(MBOX::HB_IPC_MSGQ,iv_msgQ);

    if(!err)
    {
        task_create(IpcSp::msg_handler, NULL);
    }

    return err;
}

void IpcSp::msgHandler()
{
    errlHndl_t err = NULL;
    bool mod_loaded = false;

    while(1)
    {
        msg_t* msg = msg_wait(iv_msgQ);

        switch(msg->type)
        {
            case IPC_POPULATE_TPM_INFO_BY_NODE:
            {
                // make sure runtime module is loaded
                if ( !VFS::module_is_loaded( "libruntime.so" ) )
                {
                    err = VFS::module_load( "libruntime.so" );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load runtime module - must shutdown now!!!" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    // msg->extra_data contains PAYLOAD Base
                    RUNTIME::setPayloadBaseAddress(
                               reinterpret_cast<uint64_t>(msg->extra_data));

                    // msg->data[0] contains the HDAT TPM info instance
                    // to populate
                    err = RUNTIME::populate_TpmInfoByNode(msg->data[0]);
                    if(err)
                    {
                        TRACFCOMP( g_trac_ipc, ERR_MRK"IpcSp::msgHandler: populate_TpmInfoByNode errored - must shutdown now!!!");
                    }
                }

                if (err)
                {
                    const auto l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( "libruntime.so" );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    mod_loaded = false;
                }

                // give a response back to the sender
                err = MBOX::send(MBOX::HB_POP_TPM_INFO_MSGQ, msg, msg->data[1]);
                if (err)
                {
                    const auto l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    msg_free(msg);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
            }

            case IPC_POPULATE_ATTRIBUTES:
                // make sure runtime module is loaded
                if ( !VFS::module_is_loaded( "libruntime.so" ) )
                {
                    err = VFS::module_load( "libruntime.so" );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load runtime module" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    // msg->extra_data contains PAYLOAD Base
                    RUNTIME::setPayloadBaseAddress(
                        reinterpret_cast<uint64_t>(msg->extra_data));

                    // msg->data[0] contains the node number
                    err = RUNTIME::populate_HbRsvMem( msg->data[0] );
                }

                if (err)
                {
                    TRACFCOMP( g_trac_ipc, "In ipcSp: populate_node_attribute errored - must shutdown now!!!");
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( "libruntime.so" );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    mod_loaded = false;
                }

                // Respond
                err = MBOX::send(MBOX::HB_POP_ATTR_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;

            case IPC_TEST_CONNECTION:

                TRACFCOMP( g_trac_ipc,
                           "IPC received the test connection msg - %d:%d",
                            msg->data[0], msg->data[1] );

                // Tell this HB node about the other HB node
                err = INTR::addHbNode(msg->data[1]);
                if( err)
                {
                    errlCommit(err,IPC_COMP_ID);
                }

                //Send a response to indicate the connection has been
                //established
                err = MBOX::send(MBOX::HB_COALESCE_MSGQ, msg, msg->data[1] );

                if (err)
                {
                    errlCommit(err,IPC_COMP_ID);
                }
                break;

            case IPC_QUERY_CHIPINFO:
            {
                TARGETING::TargetHandleList l_procChips;
                getAllChips( l_procChips, TARGETING::TYPE_PROC , true);
                uint64_t l_systemFabricConfigurationMap = 0x0;
                for(auto l_proc : l_procChips)
                {
                    //Get fabric info from proc
                    uint8_t l_fabricChipId =
                      l_proc->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
                    uint8_t l_fabricGroupId =
                      l_proc->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
                    //Calculate what bit position this will be
                    uint8_t l_bitPos = l_fabricChipId + (RUNTIME::MAX_PROCS_PER_NODE * l_fabricGroupId);

                    //Set the bit @ l_bitPos to be 1 because this is a functional proc
                    l_systemFabricConfigurationMap |= (0x8000000000000000 >> l_bitPos);
                }

                TRACFCOMP( g_trac_ipc,
                           "IPC Query ChipInfo 0x%lx", l_systemFabricConfigurationMap);

                //Send a response with this HB instances chip info
                msg->extra_data = reinterpret_cast<uint64_t*>(l_systemFabricConfigurationMap);
                err = MBOX::send(MBOX::HB_SBE_SYSCONFIG_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
             }
             case IPC_SET_SBE_CHIPINFO:
             {
                //Need to send System Configuration down to SBE
                //Master sends info to set into SBE via msg->extra_data
                uint64_t l_systemFabricConfigurationMap =
                        reinterpret_cast<uint64_t>(msg->extra_data);

                TRACFCOMP( g_trac_ipc,
                           "sending systemConfig[0x%lx] to SBEs",
                           l_systemFabricConfigurationMap);

                TARGETING::TargetHandleList l_procChips;
                getAllChips( l_procChips, TARGETING::TYPE_PROC , true);
                for(auto l_proc : l_procChips)
                {
                    TRACDCOMP( g_trac_ipc,
                               "calling sendSystemConfig on proc 0x%x",
                               TARGETING::get_huid(l_proc));
                    err = SBEIO::sendSystemConfig(l_systemFabricConfigurationMap,
                                                    l_proc);
                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "sendSystemConfig ERROR : Error sending sbe chip-op to proc 0x%.8X. Returning errorlog, reason=0x%x",
                                   TARGETING::get_huid(l_proc),
                                   err->reasonCode() );
                        break;
                    }
                }

                //If error terminate here
                if(err)
                {
                    TRACFCOMP( g_trac_ipc, "In ipcSp: SBEIO::sendSystemConfig errored - must shutdown now!!!");
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                else
                {
                    TRACFCOMP( g_trac_ipc,
                               "Successfully sent all system configs to procs via SBE chip op !!");
                }

                //Send response back to the master HB to indicate successful configuration down to SBE
                err = MBOX::send(MBOX::HB_SBE_SYSCONFIG_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
             }

             case IPC_START_PAYLOAD:
            {
                const int NUM_MOD = 3;
                const char * mods[NUM_MOD] =
                   {"libp9_cpuWkup.so", "libistep21.so", "libpm.so"};
                bool loaded_mods[NUM_MOD] = {false, false, false};
                for (auto cnt = 0; cnt < NUM_MOD; ++cnt)
                {
                    if ( !VFS::module_is_loaded( mods[cnt] ) )
                    {
                        err = VFS::module_load( mods[cnt] );

                        if ( err )
                        {
                            TRACFCOMP( g_trac_ipc,
                                       "Could not load %s module", mods[cnt] );
                            break;
                        }
                        else
                        {
                            loaded_mods[cnt] = true;
                        }
                    }
                }

                if (err) break;

                if(!err)
                {
                    //  Function will not return unless error
                    err = ISTEP_21::callShutdown(msg->data[0],false,
                                                                  msg->data[1]);
                }

                if(err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                for (auto cnt = 0; cnt < NUM_MOD; ++cnt)
                {
                    if ( loaded_mods[cnt] )
                    {
                        err = VFS::module_unload( mods[cnt] );

                        if (err)
                        {
                            errlCommit(err, IPC_COMP_ID);
                        }
                        loaded_mods[cnt] = false;
                    }

                }

                msg_free(msg);

                break;
            }

            case IPC_CLOSE_TCES:
            {
               TRACFCOMP( g_trac_ipc,
                          "Closing TCEs on this node (%d)",
                          TARGETING::UTIL::getCurrentNodePhysId());

                // make sure util module is loaded
                const char * libutil = "libutil.so";
                if ( !VFS::module_is_loaded( libutil ) )
                {
                    err = VFS::module_load( libutil );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load util module" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    err = TCE::utilClosePayloadTces();
                }

                if(!err)
                {
                    err = TCE::utilDisableTces();
                }

                if(err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( libutil );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    else
                    {
                        mod_loaded = false;
                    }
                }

                // Respond
                err = MBOX::send(MBOX::HB_CLOSE_TCES_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                break;
            }

            default:

                TRACFCOMP( g_trac_ipc,
                           "IPC received an unexpected message type of %d",
                           msg->type);

                /*@ errorlog tag
                 * @errortype  ERRL_SEV_INFORMATIONAL
                 * @moduleid   IPC::MOD_IPCSP_MSGHDLR
                 * @reasoncode IPC::RC_INVALID_MSG_TYPE
                 * @userdata1  Message type
                 * @userdata2  Data word 0 of message
                 *
                 * @devdesc    IPC service provider received an unexpected
                 *             message.
                 *
                 */
                err = new ERRORLOG::ErrlEntry
                    (
                     ERRORLOG::ERRL_SEV_INFORMATIONAL,    // severity
                     IPC::MOD_IPCSP_MSGHDLR,              // moduleid
                     IPC::RC_INVALID_MSG_TYPE,            // reason code
                     msg->type,
                     msg->data[0],
                     true //Add HB Software Callout
                    );
                //@todo: RTC:93750 Create real parseable FFDC class
                err->addFFDC(MBOX_COMP_ID,
                             msg,
                             sizeof(msg_t),
                             1,//version
                             MBOX::MBOX_UDT_MSG_DATA);//subsect

                err->collectTrace(MBOXMSG_TRACE_NAME);
                err->collectTrace(IPC_TRACE_NAME);

                errlCommit(err, IPC_COMP_ID);

                msg_free(msg);

                break;
        }
    }
}

<commit_msg>Fix multinode Inst storage exception on runtime call<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/mbox/ipcSp.C $                                        */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2013,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 <mbox/ipc_msg_types.H>
#include "ipcSp.H"
#include <runtime/runtime.H>
#include <vfs/vfs.H>
#include <mbox/ipc_reasoncodes.H>
#include <mbox/mboxif.H>
#include <errl/errlmanager.H>
#include <mbox/mbox_reasoncodes.H>
#include <intr/interrupt.H>
#include <initservice/initserviceif.H>
#include <sbeio/sbeioif.H>
#include <util/utiltce.H>
#include <targeting/targplatutil.H>

namespace ISTEP_21
{
    extern errlHndl_t callShutdown ( uint64_t i_hbInstance,
                                     bool i_masterInstance,
                                     const uint64_t i_commBase );
};

trace_desc_t* g_trac_ipc = NULL;
TRAC_INIT(&g_trac_ipc, IPC_TRACE_NAME, KILOBYTE);

using namespace IPC;
using namespace ERRORLOG;

IpcSp::IpcSp()
    :
        iv_msgQ()
{
}

IpcSp::~IpcSp()
{
    msg_q_destroy(iv_msgQ);
}

void IpcSp::init(errlHndl_t & o_errl)
{
    o_errl = Singleton<IpcSp>::instance()._init();
}

void* IpcSp::msg_handler(void *unused)
{
    Singleton<IpcSp>::instance().msgHandler();
    return NULL;
}

errlHndl_t IpcSp::_init()
{
    errlHndl_t err = NULL;

    iv_msgQ = msg_q_create();
    err = MBOX::msgq_register(MBOX::HB_IPC_MSGQ,iv_msgQ);

    if(!err)
    {
        task_create(IpcSp::msg_handler, NULL);
    }

    return err;
}

void IpcSp::msgHandler()
{
    errlHndl_t err = NULL;
    bool mod_loaded = false;

    while(1)
    {
        msg_t* msg = msg_wait(iv_msgQ);

        switch(msg->type)
        {
            case IPC_POPULATE_TPM_INFO_BY_NODE:
            {
                // make sure runtime module is loaded
                if ( !VFS::module_is_loaded( "libruntime.so" ) )
                {
                    err = VFS::module_load( "libruntime.so" );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load runtime module - must shutdown now!!!" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    // msg->extra_data contains PAYLOAD Base
                    RUNTIME::setPayloadBaseAddress(
                               reinterpret_cast<uint64_t>(msg->extra_data));

                    // msg->data[0] contains the HDAT TPM info instance
                    // to populate
                    err = RUNTIME::populate_TpmInfoByNode(msg->data[0]);
                    if(err)
                    {
                        TRACFCOMP( g_trac_ipc, ERR_MRK"IpcSp::msgHandler: populate_TpmInfoByNode errored - must shutdown now!!!");
                    }
                }

                if (err)
                {
                    const auto l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( "libruntime.so" );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    mod_loaded = false;
                }

                // give a response back to the sender
                err = MBOX::send(MBOX::HB_POP_TPM_INFO_MSGQ, msg, msg->data[1]);
                if (err)
                {
                    const auto l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    msg_free(msg);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
            }

            case IPC_POPULATE_ATTRIBUTES:
                // make sure runtime module is loaded
                if ( !VFS::module_is_loaded( "libruntime.so" ) )
                {
                    err = VFS::module_load( "libruntime.so" );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load runtime module" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    // msg->extra_data contains PAYLOAD Base
                    RUNTIME::setPayloadBaseAddress(
                        reinterpret_cast<uint64_t>(msg->extra_data));

                    // msg->data[0] contains the node number
                    err = RUNTIME::populate_HbRsvMem( msg->data[0] );
                }

                if (err)
                {
                    TRACFCOMP( g_trac_ipc, "In ipcSp: populate_node_attribute errored - must shutdown now!!!");
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( "libruntime.so" );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    mod_loaded = false;
                }

                // Respond
                err = MBOX::send(MBOX::HB_POP_ATTR_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;

            case IPC_TEST_CONNECTION:

                TRACFCOMP( g_trac_ipc,
                           "IPC received the test connection msg - %d:%d",
                            msg->data[0], msg->data[1] );

                // Tell this HB node about the other HB node
                err = INTR::addHbNode(msg->data[1]);
                if( err)
                {
                    errlCommit(err,IPC_COMP_ID);
                }

                //Send a response to indicate the connection has been
                //established
                err = MBOX::send(MBOX::HB_COALESCE_MSGQ, msg, msg->data[1] );

                if (err)
                {
                    errlCommit(err,IPC_COMP_ID);
                }
                break;

            case IPC_QUERY_CHIPINFO:
            {
                TARGETING::TargetHandleList l_procChips;
                getAllChips( l_procChips, TARGETING::TYPE_PROC , true);
                uint64_t l_systemFabricConfigurationMap = 0x0;
                for(auto l_proc : l_procChips)
                {
                    //Get fabric info from proc
                    uint8_t l_fabricChipId =
                      l_proc->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
                    uint8_t l_fabricGroupId =
                      l_proc->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
                    //Calculate what bit position this will be
                    uint8_t l_bitPos = l_fabricChipId + (RUNTIME::MAX_PROCS_PER_NODE * l_fabricGroupId);

                    //Set the bit @ l_bitPos to be 1 because this is a functional proc
                    l_systemFabricConfigurationMap |= (0x8000000000000000 >> l_bitPos);
                }

                TRACFCOMP( g_trac_ipc,
                           "IPC Query ChipInfo 0x%lx", l_systemFabricConfigurationMap);

                //Send a response with this HB instances chip info
                msg->extra_data = reinterpret_cast<uint64_t*>(l_systemFabricConfigurationMap);
                err = MBOX::send(MBOX::HB_SBE_SYSCONFIG_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
             }
             case IPC_SET_SBE_CHIPINFO:
             {
                //Need to send System Configuration down to SBE
                //Master sends info to set into SBE via msg->extra_data
                uint64_t l_systemFabricConfigurationMap =
                        reinterpret_cast<uint64_t>(msg->extra_data);

                TRACFCOMP( g_trac_ipc,
                           "sending systemConfig[0x%lx] to SBEs",
                           l_systemFabricConfigurationMap);

                TARGETING::TargetHandleList l_procChips;
                getAllChips( l_procChips, TARGETING::TYPE_PROC , true);
                for(auto l_proc : l_procChips)
                {
                    TRACDCOMP( g_trac_ipc,
                               "calling sendSystemConfig on proc 0x%x",
                               TARGETING::get_huid(l_proc));
                    err = SBEIO::sendSystemConfig(l_systemFabricConfigurationMap,
                                                    l_proc);
                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "sendSystemConfig ERROR : Error sending sbe chip-op to proc 0x%.8X. Returning errorlog, reason=0x%x",
                                   TARGETING::get_huid(l_proc),
                                   err->reasonCode() );
                        break;
                    }
                }

                //If error terminate here
                if(err)
                {
                    TRACFCOMP( g_trac_ipc, "In ipcSp: SBEIO::sendSystemConfig errored - must shutdown now!!!");
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                else
                {
                    TRACFCOMP( g_trac_ipc,
                               "Successfully sent all system configs to procs via SBE chip op !!");
                }

                //Send response back to the master HB to indicate successful configuration down to SBE
                err = MBOX::send(MBOX::HB_SBE_SYSCONFIG_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }
                break;
             }

             case IPC_START_PAYLOAD:
            {
                const int NUM_MOD = 4;
                const char * mods[NUM_MOD] =
                   {"libp9_cpuWkup.so", "libistep21.so", "libpm.so",
                   "libruntime.so"};
                bool loaded_mods[NUM_MOD] = {false, false, false};
                for (auto cnt = 0; cnt < NUM_MOD; ++cnt)
                {
                    if ( !VFS::module_is_loaded( mods[cnt] ) )
                    {
                        err = VFS::module_load( mods[cnt] );

                        if ( err )
                        {
                            TRACFCOMP( g_trac_ipc,
                                       "Could not load %s module", mods[cnt] );
                            break;
                        }
                        else
                        {
                            loaded_mods[cnt] = true;
                        }
                    }
                }

                if (err) break;

                if(!err)
                {
                    //  Function will not return unless error
                    err = ISTEP_21::callShutdown(msg->data[0],false,
                                                                  msg->data[1]);
                }

                if(err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                for (auto cnt = 0; cnt < NUM_MOD; ++cnt)
                {
                    if ( loaded_mods[cnt] )
                    {
                        err = VFS::module_unload( mods[cnt] );

                        if (err)
                        {
                            errlCommit(err, IPC_COMP_ID);
                        }
                        loaded_mods[cnt] = false;
                    }

                }

                msg_free(msg);

                break;
            }

            case IPC_CLOSE_TCES:
            {
               TRACFCOMP( g_trac_ipc,
                          "Closing TCEs on this node (%d)",
                          TARGETING::UTIL::getCurrentNodePhysId());

                // make sure util module is loaded
                const char * libutil = "libutil.so";
                if ( !VFS::module_is_loaded( libutil ) )
                {
                    err = VFS::module_load( libutil );

                    if ( err )
                    {
                        TRACFCOMP( g_trac_ipc,
                                   "Could not load util module" );
                    }
                    else
                    {
                        mod_loaded = true;
                    }
                }

                if(!err)
                {
                    err = TCE::utilClosePayloadTces();
                }

                if(!err)
                {
                    err = TCE::utilDisableTces();
                }

                if(err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err, IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                if(mod_loaded)
                {
                    err = VFS::module_unload( libutil );

                    if (err)
                    {
                        errlCommit(err, IPC_COMP_ID);
                    }
                    else
                    {
                        mod_loaded = false;
                    }
                }

                // Respond
                err = MBOX::send(MBOX::HB_CLOSE_TCES_MSGQ, msg, msg->data[1] );
                if (err)
                {
                    uint32_t l_errPlid = err->plid();
                    errlCommit(err,IPC_COMP_ID);
                    INITSERVICE::doShutdown(l_errPlid, true);
                }

                break;
            }

            default:

                TRACFCOMP( g_trac_ipc,
                           "IPC received an unexpected message type of %d",
                           msg->type);

                /*@ errorlog tag
                 * @errortype  ERRL_SEV_INFORMATIONAL
                 * @moduleid   IPC::MOD_IPCSP_MSGHDLR
                 * @reasoncode IPC::RC_INVALID_MSG_TYPE
                 * @userdata1  Message type
                 * @userdata2  Data word 0 of message
                 *
                 * @devdesc    IPC service provider received an unexpected
                 *             message.
                 *
                 */
                err = new ERRORLOG::ErrlEntry
                    (
                     ERRORLOG::ERRL_SEV_INFORMATIONAL,    // severity
                     IPC::MOD_IPCSP_MSGHDLR,              // moduleid
                     IPC::RC_INVALID_MSG_TYPE,            // reason code
                     msg->type,
                     msg->data[0],
                     true //Add HB Software Callout
                    );
                //@todo: RTC:93750 Create real parseable FFDC class
                err->addFFDC(MBOX_COMP_ID,
                             msg,
                             sizeof(msg_t),
                             1,//version
                             MBOX::MBOX_UDT_MSG_DATA);//subsect

                err->collectTrace(MBOXMSG_TRACE_NAME);
                err->collectTrace(IPC_TRACE_NAME);

                errlCommit(err, IPC_COMP_ID);

                msg_free(msg);

                break;
        }
    }
}

<|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 "base/android/path_utils.h"
#include "base/file_path.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace android {

typedef testing::Test PathUtilsTest;

TEST_F(PathUtilsTest, TestGetDataDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that we are packaged in
  // org.chromium.native_test
  FilePath path;
  GetDataDirectory(&path);
  EXPECT_STREQ("/data/data/org.chromium.native_test/app_chrome",
               path.value().c_str());
}

TEST_F(PathUtilsTest, TestGetCacheDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that we are packaged in
  // org.chromium.native_test
  FilePath path;
  GetCacheDirectory(&path);
  EXPECT_STREQ("/data/data/org.chromium.native_test/cache",
               path.value().c_str());
}

TEST_F(PathUtilsTest, TestGetNativeLibraryDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that we are packaged in
  // org.chromium.native_test
  FilePath path;
  GetNativeLibraryDirectory(&path);
  EXPECT_STREQ("/data/data/org.chromium.native_test/lib",
               path.value().c_str());
}

}  // namespace android
}  // namespace base
<commit_msg>Android: Fix PathUtilsTest.TestGetNativeLibraryDirectory<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 "base/android/path_utils.h"
#include "base/file_path.h"
#include "base/file_util.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace android {

typedef testing::Test PathUtilsTest;

TEST_F(PathUtilsTest, TestGetDataDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that we are packaged in
  // org.chromium.native_test
  FilePath path;
  GetDataDirectory(&path);
  EXPECT_STREQ("/data/data/org.chromium.native_test/app_chrome",
               path.value().c_str());
}

TEST_F(PathUtilsTest, TestGetCacheDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that we are packaged in
  // org.chromium.native_test
  FilePath path;
  GetCacheDirectory(&path);
  EXPECT_STREQ("/data/data/org.chromium.native_test/cache",
               path.value().c_str());
}

TEST_F(PathUtilsTest, TestGetNativeLibraryDirectory) {
  // The string comes from the Java side and depends on the APK
  // we are running in. Assumes that the directory contains
  // the base tests shared object.
  FilePath path;
  GetNativeLibraryDirectory(&path);
  EXPECT_TRUE(file_util::PathExists(path.Append(("libbase_unittests.so"))));
}

}  // namespace android
}  // namespace base
<|endoftext|>


<commit_before>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

#ifndef GCN_GUI_HPP
#define GCN_GUI_HPP

#include <string>
#include "guichan/container.hpp"
#include "guichan/input.hpp"
#include "guichan/mousetype.hpp"
#include "guichan/widget.hpp"

namespace gcn
{

  /**
   * This is the main class for Gui-chan.
   *
   * @todo Fix this comment, please.
   */
  class Gui
  {
  public:

    /**
     * Constructor.
     *
     * @todo Fix mousemessage to focused widget and offset.
     */
    Gui();

    /**
     * Destructor.
     */
    ~Gui();

    /**
     * Sets the top widget of the gui.
     *
     * @param top the top widget.
     */
    void setTop(Widget* top);

    /**
     * @return the top widget. NULL if no top widget exists.
     * @see setTop
     */
    Widget* getTop() const;

    /**
     * Sets the Graphics object to use for drawing.
     *
     * @param graphics the Graphics object to use for drawing.
     * @see Graphics, SDLGraphics, OpenGLGraphics, AllegroGraphics
     * @todo Explain about the Graphics object in this comment. (Briefly)
     */
    void setGraphics(Graphics* graphics);

    /**
     *  @return the Graphics object used for drawing. NULL if no
     *          Graphics object exists.
     */
    Graphics* getGraphics() const;

    /**
     *  Sets the Input object to use for input handling.
     *
     * @param input the Input object to use for input handling.
     * @param see Input, SDLInput, AllegroInput
     * @todo Explain about the Input object in this comment. (Briefly)
     * @todo Maybe change the tab button to be configurable.
     */
    void setInput(Input* input);

    /**
     *  @return the input object used for handling input. NULL if no
     *          Input object exists.
     */
    Input* getInput() const;

    /**
     *
     */
    void logic();

    /**
     *
     */
    void draw();

  protected:
    Widget* mTop;
    Graphics* mGraphics;
    Input* mInput;
    FocusHandler* mFocusHandler;

  }; // end class Gui

} // end gcn

#endif // end GCN_GUI_HPP
<commit_msg>Removed @todo in Gui.<commit_after>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

#ifndef GCN_GUI_HPP
#define GCN_GUI_HPP

#include <string>
#include "guichan/container.hpp"
#include "guichan/input.hpp"
#include "guichan/mousetype.hpp"
#include "guichan/widget.hpp"

namespace gcn
{

  /**
   * This is the main class for Gui-chan.
   *
   * @todo Fix this comment, please.
   */
  class Gui
  {
  public:

    /**
     * Constructor.
     */
    Gui();

    /**
     * Destructor.
     */
    ~Gui();

    /**
     * Sets the top widget of the gui.
     *
     * @param top the top widget.
     */
    void setTop(Widget* top);

    /**
     * @return the top widget. NULL if no top widget exists.
     * @see setTop
     */
    Widget* getTop() const;

    /**
     * Sets the Graphics object to use for drawing.
     *
     * @param graphics the Graphics object to use for drawing.
     * @see Graphics, SDLGraphics, OpenGLGraphics, AllegroGraphics
     * @todo Explain about the Graphics object in this comment. (Briefly)
     */
    void setGraphics(Graphics* graphics);

    /**
     *  @return the Graphics object used for drawing. NULL if no
     *          Graphics object exists.
     */
    Graphics* getGraphics() const;

    /**
     *  Sets the Input object to use for input handling.
     *
     * @param input the Input object to use for input handling.
     * @param see Input, SDLInput, AllegroInput
     * @todo Explain about the Input object in this comment. (Briefly)
     * @todo Maybe change the tab button to be configurable.
     */
    void setInput(Input* input);

    /**
     *  @return the input object used for handling input. NULL if no
     *          Input object exists.
     */
    Input* getInput() const;

    /**
     *
     */
    void logic();

    /**
     *
     */
    void draw();

  protected:
    Widget* mTop;
    Graphics* mGraphics;
    Input* mInput;
    FocusHandler* mFocusHandler;

  }; // end class Gui

} // end gcn

#endif // end GCN_GUI_HPP
<|endoftext|>


<commit_before>//
// MessagePack for C++ memory pool
//
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
//
//    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.
//
#ifndef MSGPACK_CPP11_ZONE_HPP
#define MSGPACK_CPP11_ZONE_HPP

#include "msgpack/versioning.hpp"

#include <cstdlib>
#include <memory>
#include <vector>

#include "msgpack/cpp_config.hpp"

#ifndef MSGPACK_ZONE_CHUNK_SIZE
#define MSGPACK_ZONE_CHUNK_SIZE 8192
#endif

#ifndef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN sizeof(int)
#endif

namespace msgpack {

MSGPACK_API_VERSION_NAMESPACE(v1) {

class zone {
private:
    struct finalizer {
        finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
        void operator()() { m_func(m_data); }
        void (*m_func)(void*);
        void* m_data;
    };
    struct finalizer_array {
        finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {}
        void call() {
            finalizer* fin = m_tail;
            for(; fin != m_array; --fin) (*(fin-1))();
        }
        ~finalizer_array() {
            call();
            ::free(m_array);
        }
        void clear() {
            call();
            m_tail = m_array;
        }
        void push(void (*func)(void* data), void* data)
        {
            finalizer* fin = m_tail;

            if(fin == m_end) {
                push_expand(func, data);
                return;
            }

            fin->m_func = func;
            fin->m_data = data;

            ++m_tail;
        }
        void push_expand(void (*func)(void*), void* data) {
            const size_t nused = m_end - m_array;
            size_t nnext;
            if(nused == 0) {
                nnext = (sizeof(finalizer) < 72/2) ?
                    72 / sizeof(finalizer) : 8;
            } else {
                nnext = nused * 2;
            }
            finalizer* tmp =
                static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
            if(!tmp) {
                throw std::bad_alloc();
            }
            m_array     = tmp;
            m_end   = tmp + nnext;
            m_tail  = tmp + nused;
            new (m_tail) finalizer(func, data);

            ++m_tail;
        }
#if !defined(MSGPACK_USE_CPP03)
        finalizer_array(finalizer_array&& other)
            :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
        {
            other.m_tail = nullptr;
            other.m_end = nullptr;
            other.m_array = nullptr;
        }
        finalizer_array& operator=(finalizer_array&& other)
        {
            this->~finalizer_array();
            new (this) finalizer_array(std::move(other));
            return *this;
        }
#endif
        finalizer* m_tail;
        finalizer* m_end;
        finalizer* m_array;

    private:
        finalizer_array(const finalizer_array&);
        finalizer_array& operator=(const finalizer_array&);
    };
    struct chunk {
        chunk* m_next;
    };
    struct chunk_list {
        chunk_list(size_t chunk_size)
        {
            chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
            if(!c) {
                throw std::bad_alloc();
            }

            m_head = c;
            m_free = chunk_size;
            m_ptr  = reinterpret_cast<char*>(c) + sizeof(chunk);
            c->m_next = nullptr;
        }
        ~chunk_list()
        {
            chunk* c = m_head;
            while(c) {
                chunk* n = c->m_next;
                ::free(c);
                c = n;
            }
        }
        void clear(size_t chunk_size)
        {
            chunk* c = m_head;
            while(true) {
                chunk* n = c->m_next;
                if(n) {
                    ::free(c);
                    c = n;
                } else {
                    m_head = c;
                    break;
                }
            }
            m_head->m_next = nullptr;
            m_free = chunk_size;
            m_ptr  = reinterpret_cast<char*>(m_head) + sizeof(chunk);
        }
#if !defined(MSGPACK_USE_CPP03)
        chunk_list(chunk_list&& other)
            :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
        {
            other.m_head = nullptr;
        }
        chunk_list& operator=(chunk_list&& other)
        {
            this->~chunk_list();
            new (this) chunk_list(std::move(other));
            return *this;
        }
#endif
        size_t m_free;
        char* m_ptr;
        chunk* m_head;
    private:
        chunk_list(const chunk_list&);
        chunk_list& operator=(const chunk_list&);
    };
    size_t m_chunk_size;
    chunk_list m_chunk_list;
    finalizer_array m_finalizer_array;

public:
    zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept;

public:
    void* allocate_align(size_t size);
    void* allocate_no_align(size_t size);

    void push_finalizer(void (*func)(void*), void* data);

    template <typename T>
    void push_finalizer(msgpack::unique_ptr<T> obj);

    void clear();

    void swap(zone& o);

    static void* operator new(std::size_t size) throw(std::bad_alloc)
    {
        void* p = ::malloc(size);
        if (!p) throw std::bad_alloc();
        return p;
    }
    static void operator delete(void *p) throw()
    {
        ::free(p);
    }
    static void* operator new(std::size_t /*size*/, void* mem) throw()
    {
        return mem;
    }
    static void operator delete(void * /*p*/, void* /*mem*/) throw()
    {
    }

    template <typename T, typename... Args>
    T* allocate(Args... args);

    zone(zone&&) = default;
    zone& operator=(zone&&) = default;
    zone(const zone&) = delete;
    zone& operator=(const zone&) = delete;

private:
    void undo_allocate(size_t size);

    template <typename T>
    static void object_destruct(void* obj);

    template <typename T>
    static void object_delete(void* obj);

    void* allocate_expand(size_t size);
};

inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
{
}

inline void* zone::allocate_align(size_t size)
{
    return allocate_no_align(
        ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
}

inline void* zone::allocate_no_align(size_t size)
{
    if(m_chunk_list.m_free < size) {
        return allocate_expand(size);
    }

    char* ptr = m_chunk_list.m_ptr;
    m_chunk_list.m_free -= size;
    m_chunk_list.m_ptr  += size;

    return ptr;
}

inline void* zone::allocate_expand(size_t size)
{
    chunk_list* const cl = &m_chunk_list;

    size_t sz = m_chunk_size;

    while(sz < size) {
        size_t tmp_sz = sz * 2;
        if (tmp_sz <= sz) {
            sz = size;
            break;
        }
        sz = tmp_sz;
    }

    chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
    if (!c) throw std::bad_alloc();

    char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);

    c->m_next  = cl->m_head;
    cl->m_head = c;
    cl->m_free = sz - size;
    cl->m_ptr  = ptr + size;

    return ptr;
}

inline void zone::push_finalizer(void (*func)(void*), void* data)
{
    m_finalizer_array.push(func, data);
}

template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{
    m_finalizer_array.push(&zone::object_delete<T>, obj.release());
}

inline void zone::clear()
{
    m_finalizer_array.clear();
    m_chunk_list.clear(m_chunk_size);
}

inline void zone::swap(zone& o)
{
    std::swap(*this, o);
}

template <typename T>
void zone::object_delete(void* obj)
{
    delete static_cast<T*>(obj);
}

template <typename T>
void zone::object_destruct(void* obj)
{
    static_cast<T*>(obj)->~T();
}

inline void zone::undo_allocate(size_t size)
{
    m_chunk_list.m_ptr  -= size;
    m_chunk_list.m_free += size;
}

template <typename T, typename... Args>
T* zone::allocate(Args... args)
{
    void* x = allocate_align(sizeof(T));
    try {
        m_finalizer_array.push(&zone::object_destruct<T>, x);
    } catch (...) {
        undo_allocate(sizeof(T));
        throw;
    }
    try {
        return new (x) T(args...);
    } catch (...) {
        --m_finalizer_array.m_tail;
        undo_allocate(sizeof(T));
        throw;
    }
}

}  // MSGPACK_API_VERSION_NAMESPACE(v1)

}  // namespace msgpack

#endif // MSGPACK_CPP11_ZONE_HPP
<commit_msg>Move constructors and operator= should be noexcept<commit_after>//
// MessagePack for C++ memory pool
//
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
//
//    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.
//
#ifndef MSGPACK_CPP11_ZONE_HPP
#define MSGPACK_CPP11_ZONE_HPP

#include "msgpack/versioning.hpp"

#include <cstdlib>
#include <memory>
#include <vector>

#include "msgpack/cpp_config.hpp"

#ifndef MSGPACK_ZONE_CHUNK_SIZE
#define MSGPACK_ZONE_CHUNK_SIZE 8192
#endif

#ifndef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN sizeof(int)
#endif

namespace msgpack {

MSGPACK_API_VERSION_NAMESPACE(v1) {

class zone {
private:
    struct finalizer {
        finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
        void operator()() { m_func(m_data); }
        void (*m_func)(void*);
        void* m_data;
    };
    struct finalizer_array {
        finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {}
        void call() {
            finalizer* fin = m_tail;
            for(; fin != m_array; --fin) (*(fin-1))();
        }
        ~finalizer_array() {
            call();
            ::free(m_array);
        }
        void clear() {
            call();
            m_tail = m_array;
        }
        void push(void (*func)(void* data), void* data)
        {
            finalizer* fin = m_tail;

            if(fin == m_end) {
                push_expand(func, data);
                return;
            }

            fin->m_func = func;
            fin->m_data = data;

            ++m_tail;
        }
        void push_expand(void (*func)(void*), void* data) {
            const size_t nused = m_end - m_array;
            size_t nnext;
            if(nused == 0) {
                nnext = (sizeof(finalizer) < 72/2) ?
                    72 / sizeof(finalizer) : 8;
            } else {
                nnext = nused * 2;
            }
            finalizer* tmp =
                static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
            if(!tmp) {
                throw std::bad_alloc();
            }
            m_array     = tmp;
            m_end   = tmp + nnext;
            m_tail  = tmp + nused;
            new (m_tail) finalizer(func, data);

            ++m_tail;
        }
#if !defined(MSGPACK_USE_CPP03)
        finalizer_array(finalizer_array&& other) noexcept
            :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
        {
            other.m_tail = nullptr;
            other.m_end = nullptr;
            other.m_array = nullptr;
        }
        finalizer_array& operator=(finalizer_array&& other) noexcept
        {
            this->~finalizer_array();
            new (this) finalizer_array(std::move(other));
            return *this;
        }
#endif
        finalizer* m_tail;
        finalizer* m_end;
        finalizer* m_array;

    private:
        finalizer_array(const finalizer_array&);
        finalizer_array& operator=(const finalizer_array&);
    };
    struct chunk {
        chunk* m_next;
    };
    struct chunk_list {
        chunk_list(size_t chunk_size)
        {
            chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
            if(!c) {
                throw std::bad_alloc();
            }

            m_head = c;
            m_free = chunk_size;
            m_ptr  = reinterpret_cast<char*>(c) + sizeof(chunk);
            c->m_next = nullptr;
        }
        ~chunk_list()
        {
            chunk* c = m_head;
            while(c) {
                chunk* n = c->m_next;
                ::free(c);
                c = n;
            }
        }
        void clear(size_t chunk_size)
        {
            chunk* c = m_head;
            while(true) {
                chunk* n = c->m_next;
                if(n) {
                    ::free(c);
                    c = n;
                } else {
                    m_head = c;
                    break;
                }
            }
            m_head->m_next = nullptr;
            m_free = chunk_size;
            m_ptr  = reinterpret_cast<char*>(m_head) + sizeof(chunk);
        }
#if !defined(MSGPACK_USE_CPP03)
        chunk_list(chunk_list&& other) noexcept
            :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
        {
            other.m_head = nullptr;
        }
        chunk_list& operator=(chunk_list&& other) noexcept
        {
            this->~chunk_list();
            new (this) chunk_list(std::move(other));
            return *this;
        }
#endif
        size_t m_free;
        char* m_ptr;
        chunk* m_head;
    private:
        chunk_list(const chunk_list&);
        chunk_list& operator=(const chunk_list&);
    };
    size_t m_chunk_size;
    chunk_list m_chunk_list;
    finalizer_array m_finalizer_array;

public:
    zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept;

public:
    void* allocate_align(size_t size);
    void* allocate_no_align(size_t size);

    void push_finalizer(void (*func)(void*), void* data);

    template <typename T>
    void push_finalizer(msgpack::unique_ptr<T> obj);

    void clear();

    void swap(zone& o);

    static void* operator new(std::size_t size) throw(std::bad_alloc)
    {
        void* p = ::malloc(size);
        if (!p) throw std::bad_alloc();
        return p;
    }
    static void operator delete(void *p) throw()
    {
        ::free(p);
    }
    static void* operator new(std::size_t /*size*/, void* mem) throw()
    {
        return mem;
    }
    static void operator delete(void * /*p*/, void* /*mem*/) throw()
    {
    }

    template <typename T, typename... Args>
    T* allocate(Args... args);

    zone(zone&&) = default;
    zone& operator=(zone&&) = default;
    zone(const zone&) = delete;
    zone& operator=(const zone&) = delete;

private:
    void undo_allocate(size_t size);

    template <typename T>
    static void object_destruct(void* obj);

    template <typename T>
    static void object_delete(void* obj);

    void* allocate_expand(size_t size);
};

inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
{
}

inline void* zone::allocate_align(size_t size)
{
    return allocate_no_align(
        ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
}

inline void* zone::allocate_no_align(size_t size)
{
    if(m_chunk_list.m_free < size) {
        return allocate_expand(size);
    }

    char* ptr = m_chunk_list.m_ptr;
    m_chunk_list.m_free -= size;
    m_chunk_list.m_ptr  += size;

    return ptr;
}

inline void* zone::allocate_expand(size_t size)
{
    chunk_list* const cl = &m_chunk_list;

    size_t sz = m_chunk_size;

    while(sz < size) {
        size_t tmp_sz = sz * 2;
        if (tmp_sz <= sz) {
            sz = size;
            break;
        }
        sz = tmp_sz;
    }

    chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
    if (!c) throw std::bad_alloc();

    char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);

    c->m_next  = cl->m_head;
    cl->m_head = c;
    cl->m_free = sz - size;
    cl->m_ptr  = ptr + size;

    return ptr;
}

inline void zone::push_finalizer(void (*func)(void*), void* data)
{
    m_finalizer_array.push(func, data);
}

template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{
    m_finalizer_array.push(&zone::object_delete<T>, obj.release());
}

inline void zone::clear()
{
    m_finalizer_array.clear();
    m_chunk_list.clear(m_chunk_size);
}

inline void zone::swap(zone& o)
{
    std::swap(*this, o);
}

template <typename T>
void zone::object_delete(void* obj)
{
    delete static_cast<T*>(obj);
}

template <typename T>
void zone::object_destruct(void* obj)
{
    static_cast<T*>(obj)->~T();
}

inline void zone::undo_allocate(size_t size)
{
    m_chunk_list.m_ptr  -= size;
    m_chunk_list.m_free += size;
}

template <typename T, typename... Args>
T* zone::allocate(Args... args)
{
    void* x = allocate_align(sizeof(T));
    try {
        m_finalizer_array.push(&zone::object_destruct<T>, x);
    } catch (...) {
        undo_allocate(sizeof(T));
        throw;
    }
    try {
        return new (x) T(args...);
    } catch (...) {
        --m_finalizer_array.m_tail;
        undo_allocate(sizeof(T));
        throw;
    }
}

}  // MSGPACK_API_VERSION_NAMESPACE(v1)

}  // namespace msgpack

#endif // MSGPACK_CPP11_ZONE_HPP
<|endoftext|>


<commit_before>// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "readSTL.h"
#include "list_to_matrix.h"

#include <iostream>
template <typename DerivedV, typename DerivedF, typename DerivedN>
IGL_INLINE bool igl::readSTL(
  const std::string & filename,
  Eigen::PlainObjectBase<DerivedV> & V,
  Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedN> & N)
{
  using namespace std;
  vector<vector<typename DerivedV::Scalar> > vV;
  vector<vector<typename DerivedN::Scalar> > vN;
  vector<vector<typename DerivedF::Scalar> > vF;
  if(!readSTL(filename,vV,vF,vN))
  {
    return false;
  }

  if(!list_to_matrix(vV,V))
  {
    return false;
  }

  if(!list_to_matrix(vF,F))
  {
    return false;
  }

  if(!list_to_matrix(vN,N))
  {
    return false;
  }
  return true;
}

template <typename TypeV, typename TypeF, typename TypeN>
IGL_INLINE bool igl::readSTL(
  const std::string & filename,
  std::vector<std::vector<TypeV> > & V,
  std::vector<std::vector<TypeF> > & F,
  std::vector<std::vector<TypeN> > & N)
{
  using namespace std;
  // Should test for ascii

  // Open file, and check for error
  FILE * stl_file = fopen(filename.c_str(),"r");
  if(NULL==stl_file)
  {
    fprintf(stderr,"IOError: %s could not be opened...\n",
            filename.c_str());
    return false;
  }
  V.clear();
  F.clear();
  N.clear();
#ifndef IGL_LINE_MAX
#  define IGL_LINE_MAX 2048
#endif
  char solid[IGL_LINE_MAX];
  if(fscanf(stl_file,"%s",solid)!=1)
  {
    // file too short
    cerr<<"IOError: "<<filename<<" too short."<<endl;
    goto close_false;
  }
  if(string("solid") == solid)
  {
    // Eat file name
    char name[IGL_LINE_MAX];
    if(NULL==fgets(name,IGL_LINE_MAX,stl_file))
    {
      cerr<<"IOError: "<<filename<<" too short."<<endl;
      goto close_false;
    }
    // ascii
    while(true)
    {
      int ret;
      char facet[IGL_LINE_MAX],normal[IGL_LINE_MAX];
      vector<TypeN > n(3);
      ret = fscanf(stl_file,"%s %s %lg %lg %lg",facet,normal,&n[0],&n[1],&n[2]);
      if(string("endsolid") == facet)
      {
        break;
      }
      if(ret != 5 || string("facet") != facet || string("normal") != normal)
      {
        cerr<<"IOError: "<<filename<<" bad format (1)."<<endl;
        goto close_false;
      }
      N.push_back(n);
      char outer[IGL_LINE_MAX], loop[IGL_LINE_MAX];
      ret = fscanf(stl_file,"%s %s",outer,loop);
      if(ret != 2 || string("outer") != outer || string("loop") != loop)
      {
        cerr<<"IOError: "<<filename<<" bad format (2)."<<endl;
        goto close_false;
      }
      vector<TypeF> f;
      while(true)
      {
        char word[IGL_LINE_MAX];
        int ret = fscanf(stl_file,"%s",word);
        if(ret == 1 && string("endloop") == word)
        {
          break;
        }else if(ret == 1 && string("vertex") == word)
        {
          vector<TypeV> v(3);
          int ret = fscanf(stl_file,"%lg %lg %lg",&v[0],&v[1],&v[2]);
          if(ret != 3)
          {
            cerr<<"IOError: "<<filename<<" bad format (3)."<<endl;
            goto close_false;
          }
          f.push_back(V.size());
          V.push_back(v);
        }else
        {
          cerr<<"IOError: "<<filename<<" bad format (4)."<<endl;
          goto close_false;
        }
      }
      F.push_back(f);
      char endfacet[IGL_LINE_MAX];
      ret = fscanf(stl_file,"%s",endfacet);
      if(ret != 1 || string("endfacet") != endfacet)
      {
        cerr<<"IOError: "<<filename<<" bad format (5)."<<endl;
        goto close_false;
      }
    }
    // read endfacet
    fclose(stl_file);
    goto close_true;
  }else
  {
    // Binary
    fclose(stl_file);
    stl_file = fopen(filename.c_str(),"rb");
    if(NULL==stl_file)
    {
      fprintf(stderr,"IOError: %s could not be opened...\n",
              filename.c_str());
      return false;
    }
    // Read 80 header
    char header[80];
    if(fread(header,sizeof(char),80,stl_file)!=80)
    {
      cerr<<"IOError: "<<filename<<" bad format (1)."<<endl;
      goto close_false;
    }
    // Read number of triangles
    unsigned int num_tri;
    if(fread(&num_tri,sizeof(unsigned int),1,stl_file)!=1)
    {
      cerr<<"IOError: "<<filename<<" bad format (2)."<<endl;
      goto close_false;
    }
    V.resize(num_tri*3,vector<TypeV >(3,0));
    N.resize(num_tri,vector<TypeN >(3,0));
    F.resize(num_tri,vector<TypeF >(3,0));
    for(int t = 0;t<(int)num_tri;t++)
    {
      // Read normal
      float n[3];
      if(fread(n,sizeof(float),3,stl_file)!=3)
      {
        cerr<<"IOError: "<<filename<<" bad format (3)."<<endl;
        goto close_false;
      }
      // Read each vertex
      for(int c = 0;c<3;c++)
      {
        F[t][c] = 3*t+c;
        N[t][c] = n[c];
        float v[3];
        if(fread(v,sizeof(float),3,stl_file)!=3)
        {
          cerr<<"IOError: "<<filename<<" bad format (4)."<<endl;
          goto close_false;
        }
        V[3*t+c][0] = v[0];
        V[3*t+c][1] = v[1];
        V[3*t+c][2] = v[2];
      }
      // Read attribute size
      unsigned short att_count;
      if(fread(&att_count,sizeof(unsigned short),1,stl_file)!=1)
      {
        cerr<<"IOError: "<<filename<<" bad format (5)."<<endl;
        goto close_false;
      }
    }
    goto close_true;
  }
close_false:
  fclose(stl_file);
  return false;
close_true:
  fclose(stl_file);
  return true;
}

#ifdef IGL_STATIC_LIBRARY
// Explicit template specialization
// generated by autoexplicit.sh
template bool igl::readSTL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template bool igl::readSTL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
#endif
<commit_msg>fix string format issue only supporting doubles<commit_after>// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "readSTL.h"
#include "list_to_matrix.h"

#include <iostream>
template <typename DerivedV, typename DerivedF, typename DerivedN>
IGL_INLINE bool igl::readSTL(
  const std::string & filename,
  Eigen::PlainObjectBase<DerivedV> & V,
  Eigen::PlainObjectBase<DerivedF> & F,
  Eigen::PlainObjectBase<DerivedN> & N)
{
  using namespace std;
  vector<vector<typename DerivedV::Scalar> > vV;
  vector<vector<typename DerivedN::Scalar> > vN;
  vector<vector<typename DerivedF::Scalar> > vF;
  if(!readSTL(filename,vV,vF,vN))
  {
    return false;
  }

  if(!list_to_matrix(vV,V))
  {
    return false;
  }

  if(!list_to_matrix(vF,F))
  {
    return false;
  }

  if(!list_to_matrix(vN,N))
  {
    return false;
  }
  return true;
}

template <typename TypeV, typename TypeF, typename TypeN>
IGL_INLINE bool igl::readSTL(
  const std::string & filename,
  std::vector<std::vector<TypeV> > & V,
  std::vector<std::vector<TypeF> > & F,
  std::vector<std::vector<TypeN> > & N)
{
  using namespace std;
  // Should test for ascii

  // Open file, and check for error
  FILE * stl_file = fopen(filename.c_str(),"r");
  if(NULL==stl_file)
  {
    fprintf(stderr,"IOError: %s could not be opened...\n",
            filename.c_str());
    return false;
  }
  V.clear();
  F.clear();
  N.clear();
#ifndef IGL_LINE_MAX
#  define IGL_LINE_MAX 2048
#endif
  char solid[IGL_LINE_MAX];
  if(fscanf(stl_file,"%s",solid)!=1)
  {
    // file too short
    cerr<<"IOError: "<<filename<<" too short."<<endl;
    goto close_false;
  }
  if(string("solid") == solid)
  {
    // Eat file name
    char name[IGL_LINE_MAX];
    if(NULL==fgets(name,IGL_LINE_MAX,stl_file))
    {
      cerr<<"IOError: "<<filename<<" too short."<<endl;
      goto close_false;
    }
    // ascii
    while(true)
    {
      int ret;
      char facet[IGL_LINE_MAX],normal[IGL_LINE_MAX];
      vector<TypeN > n(3);
      double nd[3];
      ret = fscanf(stl_file,"%s %s %lg %lg %lg",facet,normal,nd,nd+1,nd+2);
      if(string("endsolid") == facet)
      {
        break;
      }
      if(ret != 5 || string("facet") != facet || string("normal") != normal)
      {
        cerr<<"IOError: "<<filename<<" bad format (1)."<<endl;
        goto close_false;
      }
      // copy casts to Type
      n[0] = nd[0]; n[1] = nd[1]; n[2] = nd[2];
      N.push_back(n);
      char outer[IGL_LINE_MAX], loop[IGL_LINE_MAX];
      ret = fscanf(stl_file,"%s %s",outer,loop);
      if(ret != 2 || string("outer") != outer || string("loop") != loop)
      {
        cerr<<"IOError: "<<filename<<" bad format (2)."<<endl;
        goto close_false;
      }
      vector<TypeF> f;
      while(true)
      {
        char word[IGL_LINE_MAX];
        int ret = fscanf(stl_file,"%s",word);
        if(ret == 1 && string("endloop") == word)
        {
          break;
        }else if(ret == 1 && string("vertex") == word)
        {
          vector<TypeV> v(3);
          double vd[3];
          int ret = fscanf(stl_file,"%lg %lg %lg",vd,vd+1,vd+2);
          if(ret != 3)
          {
            cerr<<"IOError: "<<filename<<" bad format (3)."<<endl;
            goto close_false;
          }
          f.push_back(V.size());
          // copy casts to Type
          v[0] = vd[0]; v[1] = vd[1]; v[2] = vd[2];
          V.push_back(v);
        }else
        {
          cerr<<"IOError: "<<filename<<" bad format (4)."<<endl;
          goto close_false;
        }
      }
      F.push_back(f);
      char endfacet[IGL_LINE_MAX];
      ret = fscanf(stl_file,"%s",endfacet);
      if(ret != 1 || string("endfacet") != endfacet)
      {
        cerr<<"IOError: "<<filename<<" bad format (5)."<<endl;
        goto close_false;
      }
    }
    // read endfacet
    fclose(stl_file);
    goto close_true;
  }else
  {
    // Binary
    fclose(stl_file);
    stl_file = fopen(filename.c_str(),"rb");
    if(NULL==stl_file)
    {
      fprintf(stderr,"IOError: %s could not be opened...\n",
              filename.c_str());
      return false;
    }
    // Read 80 header
    char header[80];
    if(fread(header,sizeof(char),80,stl_file)!=80)
    {
      cerr<<"IOError: "<<filename<<" bad format (1)."<<endl;
      goto close_false;
    }
    // Read number of triangles
    unsigned int num_tri;
    if(fread(&num_tri,sizeof(unsigned int),1,stl_file)!=1)
    {
      cerr<<"IOError: "<<filename<<" bad format (2)."<<endl;
      goto close_false;
    }
    V.resize(num_tri*3,vector<TypeV >(3,0));
    N.resize(num_tri,vector<TypeN >(3,0));
    F.resize(num_tri,vector<TypeF >(3,0));
    for(int t = 0;t<(int)num_tri;t++)
    {
      // Read normal
      float n[3];
      if(fread(n,sizeof(float),3,stl_file)!=3)
      {
        cerr<<"IOError: "<<filename<<" bad format (3)."<<endl;
        goto close_false;
      }
      // Read each vertex
      for(int c = 0;c<3;c++)
      {
        F[t][c] = 3*t+c;
        N[t][c] = n[c];
        float v[3];
        if(fread(v,sizeof(float),3,stl_file)!=3)
        {
          cerr<<"IOError: "<<filename<<" bad format (4)."<<endl;
          goto close_false;
        }
        V[3*t+c][0] = v[0];
        V[3*t+c][1] = v[1];
        V[3*t+c][2] = v[2];
      }
      // Read attribute size
      unsigned short att_count;
      if(fread(&att_count,sizeof(unsigned short),1,stl_file)!=1)
      {
        cerr<<"IOError: "<<filename<<" bad format (5)."<<endl;
        goto close_false;
      }
    }
    goto close_true;
  }
close_false:
  fclose(stl_file);
  return false;
close_true:
  fclose(stl_file);
  return true;
}

#ifdef IGL_STATIC_LIBRARY
// Explicit template specialization
// generated by autoexplicit.sh
template bool igl::readSTL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template bool igl::readSTL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template bool igl::readSTL<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2007 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/optional/optional.hpp>
#include <boost/python.hpp>

// boost::optional<T> to/from converter from John Wiegley

template <typename T, typename TfromPy>
struct object_from_python
{
    object_from_python() {
        boost::python::converter::registry::push_back
            (&TfromPy::convertible, &TfromPy::construct,
             boost::python::type_id<T>());
    }
};

template <typename T, typename TtoPy, typename TfromPy>
struct register_python_conversion
{
    register_python_conversion() {
        boost::python::to_python_converter<T, TtoPy>();
        object_from_python<T, TfromPy>();
    }
};

template <typename T>
struct python_optional : public boost::noncopyable
{
    struct optional_to_python
    {
        static PyObject * convert(const boost::optional<T>& value)
        {
            return (value ? boost::python::to_python_value<T>()(*value) :
                    boost::python::detail::none());
        }
    };

    struct optional_from_python
    {
        static void * convertible(PyObject * source)
        {
            using namespace boost::python::converter;

            if (source == Py_None)
                return source;

            const registration& converters(registered<T>::converters);

            if (implicit_rvalue_convertible_from_python(source,
                                                        converters)) {
                rvalue_from_python_stage1_data data =
                    rvalue_from_python_stage1(source, converters);
                return rvalue_from_python_stage2(source, data, converters);
            }
            return NULL;
        }

        static void construct(PyObject * source,
                              boost::python::converter::rvalue_from_python_stage1_data * data)
        {
            using namespace boost::python::converter;

            void * const storage = ((rvalue_from_python_storage<T> *)
                                    data)->storage.bytes;

            if (data->convertible == source)        // == None
                new (storage) boost::optional<T>(); // A Boost uninitialized value
            else
                new (storage) boost::optional<T>(*static_cast<T *>(data->convertible));

            data->convertible = storage;
        }
    };

    explicit python_optional() {
        register_python_conversion<boost::optional<T>,
            optional_to_python, optional_from_python>();
    }
};

/** This class works around a bug in boost python.

  See http://osdir.com/ml/python.c++/2003-11/msg00158.html
  */
template <typename T, typename X1, typename X2, typename X3>
class class_with_optional : public boost::python::class_<T, X1, X2, X3>
{
public:
    typedef class_with_optional<T,X1,X2,X3> self;
    // Construct with the class name, with or without docstring, and default __init__() function
    class_with_optional(char const* name, char const* doc = 0) : boost::python::class_<T, X1, X2, X3>(name, doc)  { }

    // Construct with class name, no docstring, and an uncallable __init__ function
    class_with_optional(char const* name, boost::python::no_init_t y) : boost::python::class_<T, X1, X2, X3>(name, y) { }

    // Construct with class name, docstring, and an uncallable __init__ function
    class_with_optional(char const* name, char const* doc, boost::python::no_init_t y) : boost::python::class_<T, X1, X2, X3>(name, doc, y) { }

    // Construct with class name and init<> function
    template <class DerivedT> class_with_optional(char const* name, boost::python::init_base<DerivedT> const& i)
        : boost::python::class_<T, X1, X2, X3>(name, i) { }

    // Construct with class name, docstring and init<> function
    template <class DerivedT>
    inline class_with_optional(char const* name, char const* doc, boost::python::init_base<DerivedT> const& i)
        : boost::python::class_<T, X1, X2, X3>(name, doc, i) { }

    template <class D>
    self& def_readwrite_optional(char const* name, D const& d, char const* doc=0)
    {
        this->add_property(name,
                     make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),
                     make_setter(d, boost::python::default_call_policies()));
        return *this;
    }
};
<commit_msg>Add explicit namespaces. Old code compiled with clang but not with gcc.<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2007 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/optional/optional.hpp>
#include <boost/python.hpp>

// boost::optional<T> to/from converter from John Wiegley

template <typename T, typename TfromPy>
struct object_from_python
{
    object_from_python() {
        boost::python::converter::registry::push_back
            (&TfromPy::convertible, &TfromPy::construct,
             boost::python::type_id<T>());
    }
};

template <typename T, typename TtoPy, typename TfromPy>
struct register_python_conversion
{
    register_python_conversion() {
        boost::python::to_python_converter<T, TtoPy>();
        object_from_python<T, TfromPy>();
    }
};

template <typename T>
struct python_optional : public boost::noncopyable
{
    struct optional_to_python
    {
        static PyObject * convert(const boost::optional<T>& value)
        {
            return (value ? boost::python::to_python_value<T>()(*value) :
                    boost::python::detail::none());
        }
    };

    struct optional_from_python
    {
        static void * convertible(PyObject * source)
        {
            using namespace boost::python::converter;

            if (source == Py_None)
                return source;

            const registration& converters(registered<T>::converters);

            if (implicit_rvalue_convertible_from_python(source,
                                                        converters)) {
                rvalue_from_python_stage1_data data =
                    rvalue_from_python_stage1(source, converters);
                return rvalue_from_python_stage2(source, data, converters);
            }
            return NULL;
        }

        static void construct(PyObject * source,
                              boost::python::converter::rvalue_from_python_stage1_data * data)
        {
            using namespace boost::python::converter;

            void * const storage = ((rvalue_from_python_storage<T> *)
                                    data)->storage.bytes;

            if (data->convertible == source)        // == None
                new (storage) boost::optional<T>(); // A Boost uninitialized value
            else
                new (storage) boost::optional<T>(*static_cast<T *>(data->convertible));

            data->convertible = storage;
        }
    };

    explicit python_optional() {
        register_python_conversion<boost::optional<T>,
            optional_to_python, optional_from_python>();
    }
};

/** This class works around a bug in boost python.

  See http://osdir.com/ml/python.c++/2003-11/msg00158.html
  */
template <typename T, typename X1, typename X2, typename X3>
class class_with_optional : public boost::python::class_<T, X1, X2, X3>
{
public:
    typedef class_with_optional<T,X1,X2,X3> self;
    // Construct with the class name, with or without docstring, and default __init__() function
    class_with_optional(char const* name, char const* doc = 0) : boost::python::class_<T, X1, X2, X3>(name, doc)  { }

    // Construct with class name, no docstring, and an uncallable __init__ function
    class_with_optional(char const* name, boost::python::no_init_t y) : boost::python::class_<T, X1, X2, X3>(name, y) { }

    // Construct with class name, docstring, and an uncallable __init__ function
    class_with_optional(char const* name, char const* doc, boost::python::no_init_t y) : boost::python::class_<T, X1, X2, X3>(name, doc, y) { }

    // Construct with class name and init<> function
    template <class DerivedT> class_with_optional(char const* name, boost::python::init_base<DerivedT> const& i)
        : boost::python::class_<T, X1, X2, X3>(name, i) { }

    // Construct with class name, docstring and init<> function
    template <class DerivedT>
    inline class_with_optional(char const* name, char const* doc, boost::python::init_base<DerivedT> const& i)
        : boost::python::class_<T, X1, X2, X3>(name, doc, i) { }

    template <class D>
    self& def_readwrite_optional(char const* name, D const& d, char const* doc=0)
    {
        this->add_property(name,
                     boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),
                     boost::python::make_setter(d, boost::python::default_call_policies()));
        return *this;
    }
};
<|endoftext|>