<commit_before>/*-----------------------------------------------------------------------------

 Copyright 2017 Hopsan Group

    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.

 The full license is available in the file LICENSE.
 For details about the 'Hopsan Group' or information about Authors and
 Contributors see the HOPSANGROUP and AUTHORS files that are located in
 the Hopsan source code root directory.

-----------------------------------------------------------------------------*/

#ifndef FMIWRAPPER_HPP
#define FMIWRAPPER_HPP

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

#include "FMI/fmi_import_context.h"
#include <FMI1/fmi1_import.h>
#include <FMI2/fmi2_import.h>
#include <JM/jm_portability.h>

//!
//! @file FMIWrapper.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date 2021-01-27
//! @brief Wrapper component for functional mockup units (.fmu)
//!

using namespace hopsan;

void jmLogger(jm_callbacks *c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
{
    (void)module;
    hopsan::Component* pComponent = (hopsan::Component*)(c->context);
    if (pComponent) {
        switch (log_level) {
        case jm_log_level_fatal:
            pComponent->addFatalMessage(message);
            break;
        case jm_log_level_error:
            pComponent->addErrorMessage(message);
            break;
        case jm_log_level_warning:
            pComponent->addWarningMessage(message);
            break;
        // Typically the jm logger info messages are not something we want to see in Hopsan, so show them as debug type
        case jm_log_level_verbose:
        case jm_log_level_info:
        case jm_log_level_debug:
            pComponent->addDebugMessage(message);
            break;
        default:
            break;
        }
    }
}

void fmiLogger(fmi2ComponentEnvironment pComponentEnvironment, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...)
{
    hopsan::Component* pComponent = (hopsan::Component*)pComponentEnvironment;
    if (pComponent == NULL) {
        return;
    }

    char buffer[512];
    va_list args;
    va_start(args, message);
    vsnprintf(buffer, 512, message, args);
    va_end(args);

    switch (status) {
    // Typically info messages are not something we want to see in Hopsan, so show them as debug type
    case fmi2_status_ok:
        pComponent->addDebugMessage(buffer);
        break;
    case fmi2_status_warning:
        pComponent->addWarningMessage(buffer);
        break;
    case fmi2_status_error:
        pComponent->addErrorMessage(buffer);
        break;
    case fmi2_status_fatal:
        pComponent->addFatalMessage(buffer);
        break;
    default:
        // Discard
        break;
    }
}

class FMIWrapper : public ComponentSignal
{
private:
    TempDirectoryHandle *mpTempDir;
    HString mFmuPath, mLastFmuPath;
    std::map<fmi2_value_reference_t,double*> mOutputs;
    std::map<fmi2_value_reference_t,double*> mInputs;
    std::map<fmi2_value_reference_t,double> mRealParameters;
    std::map<fmi2_value_reference_t,bool> mBoolParameters;
    std::map<fmi2_value_reference_t,int> mIntParameters;
    std::map<fmi2_value_reference_t,HString> mStringParameters;
    std::vector<Port*> mPorts;

    jm_callbacks callbacks;
    jm_status_enu_t status;
    fmi_import_context_t* context;
    fmi_version_enu_t version;
    fmi2_callback_functions_t fmiCallbackFunctions;
    fmi2_status_t fmistatus;
    fmi2_import_t* fmu;

public:
    static Component *Creator()
    {
        return new FMIWrapper();
    }

    void configure()
    {
        addConstant("path", "Path to functional mockup unit (FMU)", "", mFmuPath);
        setReconfigurationParameter("path");
    }

    void reconfigure()
    {
        if(mFmuPath == mLastFmuPath) {
            return; //Path did not change, do nothing
        }
        mLastFmuPath = mFmuPath;

        deconfigure(); //Make sure to unload FMU and free memory before loading a new one

        for(int i=0; i<mPorts.size(); ++i) {
            removePort(mPorts[i]->getName());
        }
        std::vector<HString> parameters;
        this->getParameterNames(parameters);
        for(int i=0; i<parameters.size(); ++i) {
            if(parameters[i] != "path") {
                this->unRegisterParameter(parameters[i]);
            }
        }
        mPorts.clear();
        mOutputs.clear();
        mInputs.clear();
        mRealParameters.clear();
        mStringParameters.clear();
        mBoolParameters.clear();
        mIntParameters.clear();

        callbacks.malloc = malloc;
        callbacks.calloc = calloc;
        callbacks.realloc = realloc;
        callbacks.free = free;
        callbacks.logger = jmLogger;
        callbacks.log_level = jm_log_level_debug;
        callbacks.context = static_cast<jm_voidp>(this);

        context = fmi_import_allocate_context(&callbacks);

        addInfoMessage("Loading FMU from "+mFmuPath+"...");

        mpTempDir = new TempDirectoryHandle("fmu");
        if(!mpTempDir->isValid()) {
            addErrorMessage("Unable to create temp directory: "+mpTempDir->path());
            return;
        }

        addDebugMessage("Using temporary directory: "+mpTempDir->path());

        version = fmi_import_get_fmi_version(context, mFmuPath.c_str(), mpTempDir->path().c_str());
        if(version != fmi_version_2_0_enu) {
            //! @todo Implement FMI 1.0 support
            addErrorMessage("The code only supports version 2.0");
            return;
        }

        addDebugMessage("FMU version: 2.0");

        fmu = fmi2_import_parse_xml(context, mpTempDir->path().c_str(), NULL);
        if(!fmu) {
            addErrorMessage("Parsing model description failed");
            return;
        }

        addDebugMessage("Successfully parsed model description");

        if(fmi2_import_get_fmu_kind(fmu) == fmi2_fmu_kind_me) {
            addErrorMessage("Only FMI for co-simulation is supported");
            return;
        }

        addDebugMessage("FMU supports FMI for co-simulation");

        fmi2_fmu_kind_enu_t fmuKind = fmi2_import_get_fmu_kind(fmu);
        if (fmuKind == fmi2_fmu_kind_me_and_cs) {
            fmuKind = fmi2_fmu_kind_cs;
        }

        //Loop through variables in FMU and generate the lists
        fmi2_import_variable_list_t *pVarList = fmi2_import_get_variable_list(fmu,0);
        for(size_t i=0; i<fmi2_import_get_variable_list_size(pVarList); ++i)
        {
            fmi2_import_variable_t *pVar = fmi2_import_get_variable(pVarList, i);

            const char* name = fmi2_import_get_variable_name(pVar);
            const char* description = fmi2_import_get_variable_description(pVar);
            if(description == NULL) {
                description = "";
            }
            fmi2_base_type_enu_t type = fmi2_import_get_variable_base_type(pVar);
            fmi2_causality_enu_t causality = fmi2_import_get_causality(pVar);
            fmi2_value_reference_t vr = fmi2_import_get_variable_vr(pVar);

            if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_str)
            {
                addDebugMessage("String parameter: "+HString(name));
                addConstant(name, description, "", mStringParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_bool)
            {
                addDebugMessage("Boolean parameter: "+HString(name));
                addConstant(name, description, "", mBoolParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_int)
            {
                addDebugMessage("Integer parameter: "+HString(name));
                addConstant(name, description, "", mIntParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter)
            {
                addDebugMessage("Real parameter: "+HString(name));
                addConstant(name, description, "", mRealParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_input && type == fmi2_base_type_real)
            {
                addDebugMessage("Input: "+HString(name));
                mPorts.push_back(addInputVariable(name, description, "", 0, &mInputs[vr]));
            }
            else if(causality == fmi2_causality_enu_output && type == fmi2_base_type_real)
            {
                addDebugMessage("Output: "+HString(name));
                mPorts.push_back(addOutputVariable(name, description, "", &mOutputs[vr]));
            }
        }

        fmiCallbackFunctions.logger = fmiLogger;
        fmiCallbackFunctions.allocateMemory = calloc;
        fmiCallbackFunctions.freeMemory = free;
        fmiCallbackFunctions.componentEnvironment = (fmi2ComponentEnvironment*)this;

        //Load FMU binary
        status = fmi2_import_create_dllfmu(fmu, fmi2_fmu_kind_cs, &fmiCallbackFunctions);
        if (status == jm_status_error) {
            addErrorMessage("Failed to load .dll/.so file (error: "+HString(fmi2_import_get_last_error(fmu))+")");
            return;
        }

        addDebugMessage("Successfully loaded .dll/.so file");

        //Instantiate FMU
        HString instanceName = getName();
        HString resourceDir = "file://"+mpTempDir->path()+"/resources";
        fmi2_boolean_t visible = fmi2_false;
        jm_status_enu_t jmstatus = fmi2_import_instantiate(fmu, instanceName.c_str(), fmi2_cosimulation, resourceDir.c_str(), visible);
        if (jmstatus == jm_status_error) {
            stopSimulation("Failed to instantiate FMU");
            return;
        }

        addInfoMessage("Successfully instantiated FMU");

    }

    void initialize()
    {
        addInfoMessage("Initializing FMU 2.0 import");

        std::map<fmi2_value_reference_t,double>::iterator itr;
        for(itr = mRealParameters.begin(); itr != mRealParameters.end(); itr++) {
            fmistatus = fmi2_import_set_real(fmu, &itr->first, 1, &itr->second);
        }
        std::map<fmi2_value_reference_t,HString>::iterator its;
        for(its = mStringParameters.begin(); its != mStringParameters.end(); ++its) {
            const char* value = its->second.c_str();
            fmistatus = fmi2_import_set_string(fmu, &its->first, 1, &value);
        }
        std::map<fmi2_value_reference_t,bool>::iterator itb;
        for(itb = mBoolParameters.begin(); itb != mBoolParameters.end(); ++itb) {
            int value = int(itb->second);
            fmistatus = fmi2_import_set_boolean(fmu, &its->first, 1, &value);
        }
        std::map<fmi2_value_reference_t,int>::iterator iti;
        for(iti = mIntParameters.begin(); iti != mIntParameters.end(); ++iti) {
            fmistatus = fmi2_import_set_integer(fmu, &its->first, 1, &iti->second);
        }

        //Setup experiment
        fmistatus = fmi2_import_setup_experiment(fmu, fmi2_false, 0, mTime, fmi2_false, 10);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_setup_experiment() failed");
            return;
        }

        //Enter initialization mode
        fmistatus = fmi2_import_enter_initialization_mode(fmu);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_enter_initialization_mode() failed");
            return;
        }

        //Exit initialization mode
        fmistatus = fmi2_import_exit_initialization_mode(fmu);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_exit_initialization_mode() failed");
            return;
        }
    }

    void simulateOneTimestep()
    {
        //Read inputs
        std::map<fmi2_value_reference_t,double*>::iterator it;
        for(it = mInputs.begin(); it != mInputs.end(); it++) {
            fmistatus = fmi2_import_set_real(fmu, &it->first, 1, it->second);
        }

        //Take step
        fmistatus = fmi2_import_do_step(fmu, mTime, mTimestep, true);
        if (fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_do_step failed");
            return;
        }

        //Write outputs
        for(it = mOutputs.begin(); it != mOutputs.end(); it++) {
            fmistatus = fmi2_import_get_real(fmu, &it->first, 1, it->second);
        }
    }

    void finalize()
    {
        if(fmu) {
            fmistatus = fmi2_import_terminate(fmu);
        }
    }

    void deconfigure()
    {
        if(fmu) {
            fmi2_import_free_instance(fmu);
            fmi2_import_destroy_dllfmu(fmu);
            fmi2_import_free(fmu);
            fmu = NULL;
        }

        if(context) {
            fmi_import_free_context(context);
            context = NULL;
        }

        delete mpTempDir;
    }
};

#endif // FMIWRAPPER_HPP
<commit_msg>Correct calling sequence for finalize in FMIWrapper<commit_after>/*-----------------------------------------------------------------------------

 Copyright 2017 Hopsan Group

    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.

 The full license is available in the file LICENSE.
 For details about the 'Hopsan Group' or information about Authors and
 Contributors see the HOPSANGROUP and AUTHORS files that are located in
 the Hopsan source code root directory.

-----------------------------------------------------------------------------*/

#ifndef FMIWRAPPER_HPP
#define FMIWRAPPER_HPP

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

#include "FMI/fmi_import_context.h"
#include <FMI1/fmi1_import.h>
#include <FMI2/fmi2_import.h>
#include <JM/jm_portability.h>

//!
//! @file FMIWrapper.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date 2021-01-27
//! @brief Wrapper component for functional mockup units (.fmu)
//!

using namespace hopsan;

void jmLogger(jm_callbacks *c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
{
    (void)module;
    hopsan::Component* pComponent = (hopsan::Component*)(c->context);
    if (pComponent) {
        switch (log_level) {
        case jm_log_level_fatal:
            pComponent->addFatalMessage(message);
            break;
        case jm_log_level_error:
            pComponent->addErrorMessage(message);
            break;
        case jm_log_level_warning:
            pComponent->addWarningMessage(message);
            break;
        // Typically the jm logger info messages are not something we want to see in Hopsan, so show them as debug type
        case jm_log_level_verbose:
        case jm_log_level_info:
        case jm_log_level_debug:
            pComponent->addDebugMessage(message);
            break;
        default:
            break;
        }
    }
}

void fmiLogger(fmi2ComponentEnvironment pComponentEnvironment, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...)
{
    hopsan::Component* pComponent = (hopsan::Component*)pComponentEnvironment;
    if (pComponent == NULL) {
        return;
    }

    char buffer[512];
    va_list args;
    va_start(args, message);
    vsnprintf(buffer, 512, message, args);
    va_end(args);

    switch (status) {
    // Typically info messages are not something we want to see in Hopsan, so show them as debug type
    case fmi2_status_ok:
        pComponent->addDebugMessage(buffer);
        break;
    case fmi2_status_warning:
        pComponent->addWarningMessage(buffer);
        break;
    case fmi2_status_error:
        pComponent->addErrorMessage(buffer);
        break;
    case fmi2_status_fatal:
        pComponent->addFatalMessage(buffer);
        break;
    default:
        // Discard
        break;
    }
}

class FMIWrapper : public ComponentSignal
{
private:
    TempDirectoryHandle *mpTempDir;
    HString mFmuPath, mLastFmuPath;
    std::map<fmi2_value_reference_t,double*> mOutputs;
    std::map<fmi2_value_reference_t,double*> mInputs;
    std::map<fmi2_value_reference_t,double> mRealParameters;
    std::map<fmi2_value_reference_t,bool> mBoolParameters;
    std::map<fmi2_value_reference_t,int> mIntParameters;
    std::map<fmi2_value_reference_t,HString> mStringParameters;
    std::vector<Port*> mPorts;

    jm_callbacks callbacks;
    jm_status_enu_t status;
    fmi_import_context_t* context;
    fmi_version_enu_t version;
    fmi2_callback_functions_t fmiCallbackFunctions;
    fmi2_status_t fmistatus;
    fmi2_import_t* fmu;

public:
    static Component *Creator()
    {
        return new FMIWrapper();
    }

    void configure()
    {
        addConstant("path", "Path to functional mockup unit (FMU)", "", mFmuPath);
        setReconfigurationParameter("path");
    }

    void reconfigure()
    {
        if(mFmuPath == mLastFmuPath) {
            return; //Path did not change, do nothing
        }
        mLastFmuPath = mFmuPath;

        deconfigure(); //Make sure to unload FMU and free memory before loading a new one

        for(int i=0; i<mPorts.size(); ++i) {
            removePort(mPorts[i]->getName());
        }
        std::vector<HString> parameters;
        this->getParameterNames(parameters);
        for(int i=0; i<parameters.size(); ++i) {
            if(parameters[i] != "path") {
                this->unRegisterParameter(parameters[i]);
            }
        }
        mPorts.clear();
        mOutputs.clear();
        mInputs.clear();
        mRealParameters.clear();
        mStringParameters.clear();
        mBoolParameters.clear();
        mIntParameters.clear();

        callbacks.malloc = malloc;
        callbacks.calloc = calloc;
        callbacks.realloc = realloc;
        callbacks.free = free;
        callbacks.logger = jmLogger;
        callbacks.log_level = jm_log_level_debug;
        callbacks.context = static_cast<jm_voidp>(this);

        context = fmi_import_allocate_context(&callbacks);

        addInfoMessage("Loading FMU from "+mFmuPath+"...");

        mpTempDir = new TempDirectoryHandle("fmu");
        if(!mpTempDir->isValid()) {
            addErrorMessage("Unable to create temp directory: "+mpTempDir->path());
            return;
        }

        addDebugMessage("Using temporary directory: "+mpTempDir->path());

        version = fmi_import_get_fmi_version(context, mFmuPath.c_str(), mpTempDir->path().c_str());
        if(version != fmi_version_2_0_enu) {
            //! @todo Implement FMI 1.0 support
            addErrorMessage("The code only supports version 2.0");
            return;
        }

        addDebugMessage("FMU version: 2.0");

        fmu = fmi2_import_parse_xml(context, mpTempDir->path().c_str(), NULL);
        if(!fmu) {
            addErrorMessage("Parsing model description failed");
            return;
        }

        addDebugMessage("Successfully parsed model description");

        if(fmi2_import_get_fmu_kind(fmu) == fmi2_fmu_kind_me) {
            addErrorMessage("Only FMI for co-simulation is supported");
            return;
        }

        addDebugMessage("FMU supports FMI for co-simulation");

        fmi2_fmu_kind_enu_t fmuKind = fmi2_import_get_fmu_kind(fmu);
        if (fmuKind == fmi2_fmu_kind_me_and_cs) {
            fmuKind = fmi2_fmu_kind_cs;
        }

        //Loop through variables in FMU and generate the lists
        fmi2_import_variable_list_t *pVarList = fmi2_import_get_variable_list(fmu,0);
        for(size_t i=0; i<fmi2_import_get_variable_list_size(pVarList); ++i)
        {
            fmi2_import_variable_t *pVar = fmi2_import_get_variable(pVarList, i);

            const char* name = fmi2_import_get_variable_name(pVar);
            const char* description = fmi2_import_get_variable_description(pVar);
            if(description == NULL) {
                description = "";
            }
            fmi2_base_type_enu_t type = fmi2_import_get_variable_base_type(pVar);
            fmi2_causality_enu_t causality = fmi2_import_get_causality(pVar);
            fmi2_value_reference_t vr = fmi2_import_get_variable_vr(pVar);

            if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_str)
            {
                addDebugMessage("String parameter: "+HString(name));
                addConstant(name, description, "", mStringParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_bool)
            {
                addDebugMessage("Boolean parameter: "+HString(name));
                addConstant(name, description, "", mBoolParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter && type == fmi2_base_type_int)
            {
                addDebugMessage("Integer parameter: "+HString(name));
                addConstant(name, description, "", mIntParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_parameter)
            {
                addDebugMessage("Real parameter: "+HString(name));
                addConstant(name, description, "", mRealParameters[vr]);
            }
            else if(causality == fmi2_causality_enu_input && type == fmi2_base_type_real)
            {
                addDebugMessage("Input: "+HString(name));
                mPorts.push_back(addInputVariable(name, description, "", 0, &mInputs[vr]));
            }
            else if(causality == fmi2_causality_enu_output && type == fmi2_base_type_real)
            {
                addDebugMessage("Output: "+HString(name));
                mPorts.push_back(addOutputVariable(name, description, "", &mOutputs[vr]));
            }
        }

        fmiCallbackFunctions.logger = fmiLogger;
        fmiCallbackFunctions.allocateMemory = calloc;
        fmiCallbackFunctions.freeMemory = free;
        fmiCallbackFunctions.componentEnvironment = (fmi2ComponentEnvironment*)this;

        //Load FMU binary
        status = fmi2_import_create_dllfmu(fmu, fmi2_fmu_kind_cs, &fmiCallbackFunctions);
        if (status == jm_status_error) {
            addErrorMessage("Failed to load .dll/.so file (error: "+HString(fmi2_import_get_last_error(fmu))+")");
            return;
        }

        addDebugMessage("Successfully loaded .dll/.so file");

        //Instantiate FMU
        HString instanceName = getName();
        HString resourceDir = "file://"+mpTempDir->path()+"/resources";
        fmi2_boolean_t visible = fmi2_false;
        jm_status_enu_t jmstatus = fmi2_import_instantiate(fmu, instanceName.c_str(), fmi2_cosimulation, resourceDir.c_str(), visible);
        if (jmstatus == jm_status_error) {
            stopSimulation("Failed to instantiate FMU");
            return;
        }

        addInfoMessage("Successfully instantiated FMU");

    }

    void initialize()
    {
        addInfoMessage("Initializing FMU 2.0 import");

        std::map<fmi2_value_reference_t,double>::iterator itr;
        for(itr = mRealParameters.begin(); itr != mRealParameters.end(); itr++) {
            fmistatus = fmi2_import_set_real(fmu, &itr->first, 1, &itr->second);
        }
        std::map<fmi2_value_reference_t,HString>::iterator its;
        for(its = mStringParameters.begin(); its != mStringParameters.end(); ++its) {
            const char* value = its->second.c_str();
            fmistatus = fmi2_import_set_string(fmu, &its->first, 1, &value);
        }
        std::map<fmi2_value_reference_t,bool>::iterator itb;
        for(itb = mBoolParameters.begin(); itb != mBoolParameters.end(); ++itb) {
            int value = int(itb->second);
            fmistatus = fmi2_import_set_boolean(fmu, &its->first, 1, &value);
        }
        std::map<fmi2_value_reference_t,int>::iterator iti;
        for(iti = mIntParameters.begin(); iti != mIntParameters.end(); ++iti) {
            fmistatus = fmi2_import_set_integer(fmu, &its->first, 1, &iti->second);
        }

        //Setup experiment
        fmistatus = fmi2_import_setup_experiment(fmu, fmi2_false, 0, mTime, fmi2_false, 10);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_setup_experiment() failed");
            return;
        }

        //Enter initialization mode
        fmistatus = fmi2_import_enter_initialization_mode(fmu);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_enter_initialization_mode() failed");
            return;
        }

        //Exit initialization mode
        fmistatus = fmi2_import_exit_initialization_mode(fmu);
        if(fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_exit_initialization_mode() failed");
            return;
        }
    }

    void simulateOneTimestep()
    {
        //Read inputs
        std::map<fmi2_value_reference_t,double*>::iterator it;
        for(it = mInputs.begin(); it != mInputs.end(); it++) {
            fmistatus = fmi2_import_set_real(fmu, &it->first, 1, it->second);
        }

        //Take step
        fmistatus = fmi2_import_do_step(fmu, mTime, mTimestep, true);
        if (fmistatus != fmi2_status_ok) {
            stopSimulation("fmi2_import_do_step failed");
            return;
        }

        //Write outputs
        for(it = mOutputs.begin(); it != mOutputs.end(); it++) {
            fmistatus = fmi2_import_get_real(fmu, &it->first, 1, it->second);
        }
    }

    void finalize()
    {
        if(fmu) {
            fmistatus = fmi2_import_reset(fmu);
        }
    }

    void deconfigure()
    {
        if(fmu) {
            fmistatus = fmi2_import_terminate(fmu);
            fmi2_import_free_instance(fmu);
            fmi2_import_destroy_dllfmu(fmu);
            fmi2_import_free(fmu);
            fmu = NULL;
        }

        if(context) {
            fmi_import_free_context(context);
            context = NULL;
        }

        delete mpTempDir;
    }
};

#endif // FMIWRAPPER_HPP
<|endoftext|>


<commit_before>#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <map>
#include <list>

using namespace std;

// this function takes a line that may contain a name and/or email address,
// and returns just the name, while fixing the "bad cases".
std::string contributor_name(const std::string& line)
{
  string result;
  size_t position_of_email_address = line.find_first_of('<');
  if(position_of_email_address != string::npos)
  {
    // there is an e-mail address.

    // Hauke once committed as "John Smith", fix that.
    if(line.find("hauke.heibel") != string::npos)
      result = "Hauke Heibel";
    else
    {
      // just remove the e-mail address
      result = line.substr(0, position_of_email_address);
    }
  }
  else
  {
    // there is no e-mail address.

    if(line.find("convert-repo") != string::npos)
      result = "";
    else
      result = line;
  }

  // remove trailing spaces
  size_t length = result.length();
  while(length >= 1 && result[length-1] == ' ') result.erase(--length);

  return result;
}

// parses hg churn output to generate a contributors map.
map<string,int> contributors_map_from_churn_output(const char *filename)
{
  map<string,int> contributors_map;

  string line;
  ifstream churn_out;
  churn_out.open(filename, ios::in);
  while(!getline(churn_out,line).eof())
  {
    // remove the histograms "******" that hg churn may draw at the end of some lines
    size_t first_star = line.find_first_of('*');
    if(first_star != string::npos) line.erase(first_star);

    // remove trailing spaces
    size_t length = line.length();
    while(length >= 1 && line[length-1] == ' ') line.erase(--length);

    // now the last space indicates where the number starts
    size_t last_space = line.find_last_of(' ');

    // get the number (of changesets or of modified lines for each contributor)
    int number;
    istringstream(line.substr(last_space+1)) >> number;

    // get the name of the contributor
    line.erase(last_space);
    string name = contributor_name(line);

    map<string,int>::iterator it = contributors_map.find(name);
    // if new contributor, insert
    if(it == contributors_map.end())
      contributors_map.insert(pair<string,int>(name, number));
    // if duplicate, just add the number
    else
      it->second += number;
  }
  churn_out.close();

  return contributors_map;
}

struct contributor
{
  string name;
  int changedlines;
  int changesets;
  string url;
  string misc;

  contributor() : changedlines(0), changesets(0) {}

  bool operator < (const contributor& other)
  {
    return changedlines > other.changedlines;
  }
};

void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
{
  string line;
  ifstream online_info;
  online_info.open(filename, ios::in);
  while(!getline(online_info,line).eof())
  {
    string hgname, realname, url, misc;

    size_t last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      misc = line.substr(last_bar+1);
    line.erase(last_bar);

    last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      url = line.substr(last_bar+1);
    line.erase(last_bar);

    last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      realname = line.substr(last_bar+1);
    line.erase(last_bar);

    hgname = line;

    // remove the example line
    if(hgname.find("MercurialName") != string::npos) continue;

    list<contributor>::iterator it;
    for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
    {}

    if(it == contributors_list.end())
    {
      contributor c;
      c.name = realname;
      c.url = url;
      c.misc = misc;
      contributors_list.push_back(c);
    }
    else
    {
      it->name = realname;
      it->url = url;
      it->misc = misc;
    }
  }
}

ostream& operator<<(ostream& stream, const contributor& c)
{
  stream << c.name << "|" << c.changedlines << "|" << c.changesets << "|" << c.url << "|" << c.misc;
}

int main()
{
  // parse the hg churn output files
  map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
  map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");

  // merge into the contributors list
  list<contributor> contributors_list;
  map<string,int>::iterator it;
  for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
  {
    contributor c;
    c.name = it->first;
    c.changedlines = it->second;
    c.changesets = contributors_map_for_changesets.find(it->first)->second;
    contributors_list.push_back(c);
  }

  add_online_info_into_contributors_list(contributors_list, "online-info.out");

  contributors_list.sort();

  cout << "{| cellpadding=\"5\"\n";
  cout << "!\n";
  cout << "! Lines changed\n(changesets)\n";
  cout << "! Misc\n";

  list<contributor>::iterator itc;
  int i = 0;
  for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
  {
    if(itc->name.length() == 0) continue;
    if(i%2) cout << "|-\n";
    else cout << "|- style=\"background:#FFFFD0\"\n";
    if(itc->url.length())
      cout << "| [" << itc->url << " " << itc->name << "]\n";
    else
      cout << "| " << itc->name << "\n";
    if(itc->changedlines)
      cout << "| " << itc->changedlines << " (" << itc->changesets << ")\n";
    else
      cout << "| (no own changesets) \n";
    cout << "| " << itc->misc << "\n";
    i++;
  }
  cout << "|}" << endl;
}
<commit_msg>* sort by last name alphabetically * replace (no own changesets) by (no information)<commit_after>#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <map>
#include <list>

using namespace std;

// this function takes a line that may contain a name and/or email address,
// and returns just the name, while fixing the "bad cases".
std::string contributor_name(const std::string& line)
{
  string result;
  size_t position_of_email_address = line.find_first_of('<');
  if(position_of_email_address != string::npos)
  {
    // there is an e-mail address.

    // Hauke once committed as "John Smith", fix that.
    if(line.find("hauke.heibel") != string::npos)
      result = "Hauke Heibel";
    else
    {
      // just remove the e-mail address
      result = line.substr(0, position_of_email_address);
    }
  }
  else
  {
    // there is no e-mail address.

    if(line.find("convert-repo") != string::npos)
      result = "";
    else
      result = line;
  }

  // remove trailing spaces
  size_t length = result.length();
  while(length >= 1 && result[length-1] == ' ') result.erase(--length);

  return result;
}

// parses hg churn output to generate a contributors map.
map<string,int> contributors_map_from_churn_output(const char *filename)
{
  map<string,int> contributors_map;

  string line;
  ifstream churn_out;
  churn_out.open(filename, ios::in);
  while(!getline(churn_out,line).eof())
  {
    // remove the histograms "******" that hg churn may draw at the end of some lines
    size_t first_star = line.find_first_of('*');
    if(first_star != string::npos) line.erase(first_star);

    // remove trailing spaces
    size_t length = line.length();
    while(length >= 1 && line[length-1] == ' ') line.erase(--length);

    // now the last space indicates where the number starts
    size_t last_space = line.find_last_of(' ');

    // get the number (of changesets or of modified lines for each contributor)
    int number;
    istringstream(line.substr(last_space+1)) >> number;

    // get the name of the contributor
    line.erase(last_space);
    string name = contributor_name(line);

    map<string,int>::iterator it = contributors_map.find(name);
    // if new contributor, insert
    if(it == contributors_map.end())
      contributors_map.insert(pair<string,int>(name, number));
    // if duplicate, just add the number
    else
      it->second += number;
  }
  churn_out.close();

  return contributors_map;
}

// find the last name, i.e. the last word.
// for "van den Schbling" types of last names, that's not a problem, that's actually what we want.
string lastname(const string& name)
{
  size_t last_space = name.find_last_of(' ');
  if(last_space >= name.length()-1) return name;
  else return name.substr(last_space+1);
}

struct contributor
{
  string name;
  int changedlines;
  int changesets;
  string url;
  string misc;

  contributor() : changedlines(0), changesets(0) {}

  bool operator < (const contributor& other)
  {
    return lastname(name).compare(lastname(other.name)) < 0;
  }
};

void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
{
  string line;
  ifstream online_info;
  online_info.open(filename, ios::in);
  while(!getline(online_info,line).eof())
  {
    string hgname, realname, url, misc;

    size_t last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      misc = line.substr(last_bar+1);
    line.erase(last_bar);

    last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      url = line.substr(last_bar+1);
    line.erase(last_bar);

    last_bar = line.find_last_of('|');
    if(last_bar == string::npos) continue;
    if(last_bar < line.length())
      realname = line.substr(last_bar+1);
    line.erase(last_bar);

    hgname = line;

    // remove the example line
    if(hgname.find("MercurialName") != string::npos) continue;

    list<contributor>::iterator it;
    for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
    {}

    if(it == contributors_list.end())
    {
      contributor c;
      c.name = realname;
      c.url = url;
      c.misc = misc;
      contributors_list.push_back(c);
    }
    else
    {
      it->name = realname;
      it->url = url;
      it->misc = misc;
    }
  }
}

int main()
{
  // parse the hg churn output files
  map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
  map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");

  // merge into the contributors list
  list<contributor> contributors_list;
  map<string,int>::iterator it;
  for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
  {
    contributor c;
    c.name = it->first;
    c.changedlines = it->second;
    c.changesets = contributors_map_for_changesets.find(it->first)->second;
    contributors_list.push_back(c);
  }

  add_online_info_into_contributors_list(contributors_list, "online-info.out");

  contributors_list.sort();

  cout << "{| cellpadding=\"5\"\n";
  cout << "!\n";
  cout << "! Lines changed\n(changesets)\n";
  cout << "!\n";

  list<contributor>::iterator itc;
  int i = 0;
  for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
  {
    if(itc->name.length() == 0) continue;
    if(i%2) cout << "|-\n";
    else cout << "|- style=\"background:#FFFFD0\"\n";
    if(itc->url.length())
      cout << "| [" << itc->url << " " << itc->name << "]\n";
    else
      cout << "| " << itc->name << "\n";
    if(itc->changedlines)
      cout << "| " << itc->changedlines << " (" << itc->changesets << ")\n";
    else
      cout << "| (no information)\n";
    cout << "| " << itc->misc << "\n";
    i++;
  }
  cout << "|}" << endl;
}
<|endoftext|>


<commit_before><commit_msg>Removed empty file<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DTextureResource.h"

void GrD3DTextureResource::setResourceState(const GrD3DGpu* gpu,
                                            D3D12_RESOURCE_STATES newResourceState) {
    D3D12_RESOURCE_STATES currentResourceState = this->currentState();
    if (newResourceState == currentResourceState) {
        return;
    }

    D3D12_RESOURCE_TRANSITION_BARRIER barrier;
    barrier.pResource = this->d3dResource();
    barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    barrier.StateBefore = currentResourceState;
    barrier.StateAfter = newResourceState;
    gpu->addResourceBarriers(this->resource(), 1, &barrier);

    this->updateResourceState(newResourceState);
}

bool GrD3DTextureResource::InitTextureResourceInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
                                                   D3D12_RESOURCE_STATES initialState,
                                                   GrProtected isProtected,
                                                   D3D12_CLEAR_VALUE* clearValue,
                                                   GrD3DTextureResourceInfo* info) {
    if (0 == desc.Width || 0 == desc.Height) {
        return false;
    }
    // TODO: We don't support protected memory at the moment
    if (isProtected == GrProtected::kYes) {
        return false;
    }
    // If MipLevels is 0, for some formats the API will automatically calculate the maximum
    // number of levels supported and use that -- we don't support that.
    SkASSERT(desc.MipLevels > 0);

    ID3D12Resource* resource = nullptr;

    D3D12_HEAP_PROPERTIES heapProperties = {};
    heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
    heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
    heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    heapProperties.CreationNodeMask = 1;
    heapProperties.VisibleNodeMask = 1;
    HRESULT hr = gpu->device()->CreateCommittedResource(
        &heapProperties,
        D3D12_HEAP_FLAG_NONE,
        &desc,
        initialState,
        clearValue,
        IID_PPV_ARGS(&resource));
    if (!SUCCEEDED(hr)) {
        return false;
    }

    info->fResource.reset(resource);
    info->fResourceState = initialState;
    info->fFormat = desc.Format;
    info->fLevelCount = desc.MipLevels;
    info->fSampleQualityPattern = desc.SampleDesc.Quality;
    info->fProtected = isProtected;

    return true;
}

std::pair<GrD3DTextureResourceInfo, sk_sp<GrD3DResourceState>> GrD3DTextureResource::CreateMSAA(
        GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
        SkColor4f clearColor) {
    GrD3DTextureResourceInfo msInfo;
    sk_sp<GrD3DResourceState> msState;

    // create msaa surface
    D3D12_RESOURCE_DESC msTextureDesc = {};
    msTextureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    msTextureDesc.Alignment = 0;  // Default alignment (64KB)
    msTextureDesc.Width = dimensions.fWidth;
    msTextureDesc.Height = dimensions.fHeight;
    msTextureDesc.DepthOrArraySize = 1;
    msTextureDesc.MipLevels = 1;
    msTextureDesc.Format = info.fFormat;
    msTextureDesc.SampleDesc.Count = sampleCnt;
    msTextureDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
    msTextureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;  // Use default for dxgi format
    msTextureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;

    D3D12_CLEAR_VALUE clearValue = {};
    clearValue.Format = info.fFormat;
    clearValue.Color[0] = clearColor.fR;
    clearValue.Color[1] = clearColor.fG;
    clearValue.Color[2] = clearColor.fB;
    clearValue.Color[3] = clearColor.fA;

    if (!InitTextureResourceInfo(gpu, msTextureDesc, D3D12_RESOURCE_STATE_RENDER_TARGET,
                                 info.fProtected, &clearValue, &msInfo)) {
        return {};
    }

    msState.reset(new GrD3DResourceState(
            static_cast<D3D12_RESOURCE_STATES>(msInfo.fResourceState)));

    return std::make_pair(msInfo, msState);
}

GrD3DTextureResource::~GrD3DTextureResource() {
    // Should have been reset() before
    SkASSERT(!fResource);
}

void GrD3DTextureResource::prepareForPresent(GrD3DGpu* gpu) {
    this->setResourceState(gpu, D3D12_RESOURCE_STATE_PRESENT);
}

void GrD3DTextureResource::releaseResource(GrD3DGpu* gpu) {
    // TODO: do we need to migrate resource state if we change queues?
    if (fResource) {
        fResource->removeOwningTexture();
        fResource.reset(nullptr);
    }
}

void GrD3DTextureResource::setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper) {
    SkASSERT(fResource);
    // Forward the release proc on to GrD3DTextureResource::Resource
    fResource->setRelease(std::move(releaseHelper));
}

void GrD3DTextureResource::Resource::freeGPUData() const {
    this->invokeReleaseProc();
    fResource.reset();  // Release our ref to the resource
}
<commit_msg>Make sure we release all refs in GrD3DTextureResource::releaseResource.<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DTextureResource.h"

void GrD3DTextureResource::setResourceState(const GrD3DGpu* gpu,
                                            D3D12_RESOURCE_STATES newResourceState) {
    D3D12_RESOURCE_STATES currentResourceState = this->currentState();
    if (newResourceState == currentResourceState) {
        return;
    }

    D3D12_RESOURCE_TRANSITION_BARRIER barrier;
    barrier.pResource = this->d3dResource();
    barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    barrier.StateBefore = currentResourceState;
    barrier.StateAfter = newResourceState;
    gpu->addResourceBarriers(this->resource(), 1, &barrier);

    this->updateResourceState(newResourceState);
}

bool GrD3DTextureResource::InitTextureResourceInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
                                                   D3D12_RESOURCE_STATES initialState,
                                                   GrProtected isProtected,
                                                   D3D12_CLEAR_VALUE* clearValue,
                                                   GrD3DTextureResourceInfo* info) {
    if (0 == desc.Width || 0 == desc.Height) {
        return false;
    }
    // TODO: We don't support protected memory at the moment
    if (isProtected == GrProtected::kYes) {
        return false;
    }
    // If MipLevels is 0, for some formats the API will automatically calculate the maximum
    // number of levels supported and use that -- we don't support that.
    SkASSERT(desc.MipLevels > 0);

    ID3D12Resource* resource = nullptr;

    D3D12_HEAP_PROPERTIES heapProperties = {};
    heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
    heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
    heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    heapProperties.CreationNodeMask = 1;
    heapProperties.VisibleNodeMask = 1;
    HRESULT hr = gpu->device()->CreateCommittedResource(
        &heapProperties,
        D3D12_HEAP_FLAG_NONE,
        &desc,
        initialState,
        clearValue,
        IID_PPV_ARGS(&resource));
    if (!SUCCEEDED(hr)) {
        return false;
    }

    info->fResource.reset(resource);
    info->fResourceState = initialState;
    info->fFormat = desc.Format;
    info->fLevelCount = desc.MipLevels;
    info->fSampleQualityPattern = desc.SampleDesc.Quality;
    info->fProtected = isProtected;

    return true;
}

std::pair<GrD3DTextureResourceInfo, sk_sp<GrD3DResourceState>> GrD3DTextureResource::CreateMSAA(
        GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
        SkColor4f clearColor) {
    GrD3DTextureResourceInfo msInfo;
    sk_sp<GrD3DResourceState> msState;

    // create msaa surface
    D3D12_RESOURCE_DESC msTextureDesc = {};
    msTextureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    msTextureDesc.Alignment = 0;  // Default alignment (64KB)
    msTextureDesc.Width = dimensions.fWidth;
    msTextureDesc.Height = dimensions.fHeight;
    msTextureDesc.DepthOrArraySize = 1;
    msTextureDesc.MipLevels = 1;
    msTextureDesc.Format = info.fFormat;
    msTextureDesc.SampleDesc.Count = sampleCnt;
    msTextureDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
    msTextureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;  // Use default for dxgi format
    msTextureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;

    D3D12_CLEAR_VALUE clearValue = {};
    clearValue.Format = info.fFormat;
    clearValue.Color[0] = clearColor.fR;
    clearValue.Color[1] = clearColor.fG;
    clearValue.Color[2] = clearColor.fB;
    clearValue.Color[3] = clearColor.fA;

    if (!InitTextureResourceInfo(gpu, msTextureDesc, D3D12_RESOURCE_STATE_RENDER_TARGET,
                                 info.fProtected, &clearValue, &msInfo)) {
        return {};
    }

    msState.reset(new GrD3DResourceState(
            static_cast<D3D12_RESOURCE_STATES>(msInfo.fResourceState)));

    return std::make_pair(msInfo, msState);
}

GrD3DTextureResource::~GrD3DTextureResource() {
    // Should have been reset() before
    SkASSERT(!fResource);
    SkASSERT(!fInfo.fResource);
}

void GrD3DTextureResource::prepareForPresent(GrD3DGpu* gpu) {
    this->setResourceState(gpu, D3D12_RESOURCE_STATE_PRESENT);
}

void GrD3DTextureResource::releaseResource(GrD3DGpu* gpu) {
    // TODO: do we need to migrate resource state if we change queues?
    if (fResource) {
        fResource->removeOwningTexture();
        fResource.reset();
    }
    fInfo.fResource.reset();
}

void GrD3DTextureResource::setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper) {
    SkASSERT(fResource);
    // Forward the release proc on to GrD3DTextureResource::Resource
    fResource->setRelease(std::move(releaseHelper));
}

void GrD3DTextureResource::Resource::freeGPUData() const {
    this->invokeReleaseProc();
    fResource.reset();  // Release our ref to the resource
}
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2012 Michael Marner <michael@20papercups.net>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "MatrixSwitch.h"

namespace wcl
{

	MatrixSwitch::MatrixSwitch(const std::string& ipAddress, unsigned int switchID)
		: mIP(ipAddress), mSwitchID(switchID)
	{
		// nothing to do here...
	}

	MatrixSwitch::~MatrixSwitch()
	{
		// nothing to do here either...
	}

	bool MatrixSwitch::route(unsigned int inputID, unsigned int outputID)
	{
		// note: I don't know how many simultaneous connections
		// the matrix switch supports. So, rather than connect
		// on creation and disconnect on destruction, we'll just
		// create a socket each method call.

		if (inputID < 1 && inputID >36 && outputID < 1 && outputID > 36)
			return false;

		// connects on port 23 always
		wcl::TCPSocket s(mIP, 23);

		char message[14];
		message[13] = 0;

		sprintf(message, "*%3d0004%2d%2d!", mSwitchID, outputID, inputID);
		s.writeUntil(message, 13);
		s.close();

        return true;
	}

	bool MatrixSwitch::disconnect(unsigned int outputID)
	{
		if (outputID < 1 && outputID > 36)
			return false;

		// connects on port 23 always
		wcl::TCPSocket s(mIP, 23);

		char message[14];
		message[13] = 0;

		sprintf(message, "*%3d0004%2d%2d!", mSwitchID, outputID, 0);
		s.writeUntil(message, 13);
		s.close();

        return true;
	}

};

<commit_msg>Fix return value when routing.<commit_after>/*-
 * Copyright (c) 2012 Michael Marner <michael@20papercups.net>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "MatrixSwitch.h"

namespace wcl
{

	MatrixSwitch::MatrixSwitch(const std::string& ipAddress, unsigned int switchID)
		: mIP(ipAddress), mSwitchID(switchID)
	{
		// nothing to do here...
	}

	MatrixSwitch::~MatrixSwitch()
	{
		// nothing to do here either...
	}

	bool MatrixSwitch::route(unsigned int inputID, unsigned int outputID)
	{
		// note: I don't know how many simultaneous connections
		// the matrix switch supports. So, rather than connect
		// on creation and disconnect on destruction, we'll just
		// create a socket each method call.

		if (inputID < 1 && inputID >36 && outputID < 1 && outputID > 36)
			return false;

		// connects on port 23 always
		wcl::TCPSocket s(mIP, 23);

		char message[14];
		message[13] = 0;

		sprintf(message, "*%3d0004%2d%2d!", mSwitchID, outputID, inputID);
		s.writeUntil(message, 13);
		s.close();
		return true;
	}

	bool MatrixSwitch::disconnect(unsigned int outputID)
	{
		if (outputID < 1 && outputID > 36)
			return false;

		// connects on port 23 always
		wcl::TCPSocket s(mIP, 23);

		char message[14];
		message[13] = 0;

		sprintf(message, "*%3d0004%2d%2d!", mSwitchID, outputID, 0);
		s.writeUntil(message, 13);
		s.close();
		return true;
	}

};

<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_LOG_MIX_HPP
#define STAN_MATH_PRIM_MAT_FUN_LOG_MIX_HPP

#include <stan/math/prim/scal/meta/partials_return_type.hpp>
#include <stan/math/prim/scal/meta/operands_and_partials.hpp>
#include <stan/math/prim/scal/meta/scalar_seq_view.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/prim/scal/err/check_bounded.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/mat/meta/is_constant_struct.hpp>
#include <stan/math/prim/mat/fun/log_sum_exp.hpp>
#include <stan/math/prim/mat/fun/log.hpp>
#include <stan/math/prim/mat/fun/exp.hpp>
#include <stan/math/prim/mat/fun/max.hpp>
#include <stan/math/prim/mat/fun/dot_product.hpp>
#include <stan/math/prim/mat/fun/value_of.hpp>
#include <stan/math/prim/mat/fun/value_of_rec.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <string>

namespace stan {
  namespace math {

    /**
     * Return the log mixture density with specified mixing proportion
     * and log densities.
     *
     *
     * @param theta vector of mixing proportions in [0, 1].
     * @param lambda vector of log densities.
     * @return log mixture of densities in specified proportion
     */
    template <typename T_theta, typename T_lam>
    typename return_type<T_theta, T_lam>::type
    log_mix(const T_theta& theta,
            const T_lam& lambda) {
      static const std::string function = "log_mix";
    typedef typename stan::partials_return_type<T_theta, T_lam>::type
      T_partials_return;

      const size_t N = theta.size();

      for (size_t n = 0; n < N; ++n) {
        check_not_nan(function, "lambda", lambda[n]);
        check_not_nan(function, "theta", theta[n]);
        check_finite(function, "lambda", lambda[n]);
        check_finite(function, "theta", theta[n]);
        check_bounded(function, "theta", theta[n], 0, 1);
      }
      check_consistent_sizes(function, "theta", theta, "lambda", lambda);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> theta_dbl(N, 1);
      scalar_seq_view<T_theta> theta_vec(theta);
        for (size_t n = 0; n < N; ++n)
          theta_dbl[n] = value_of(theta_vec[n]);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> lambda_dbl(N, 1);
      scalar_seq_view<T_lam> lam_vec(lambda);
        for (size_t n = 0; n < N; ++n)
          lambda_dbl[n] = value_of(lam_vec[n]);

      /**
       * Vector containing log-prob of each density, log_sum_exp applied as
       * part of return call.
       */
      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> logp_tmp(N, 1);
        logp_tmp = log(theta_dbl) + lambda_dbl;

      /**
       * Calculate derivatives
       */
      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> exp_lambda_dbl(N, 1);
      /**
       * Exp-normalise to prevent overflow, as:
       * (exp(x-a) * exp(a)) / (exp(y-a) * exp(a)) = exp(x-a) / exp(y-a)
       */
      double max_val = max(lambda_dbl);
        for (size_t n = 0; n < N; ++n)
          exp_lambda_dbl[n] = exp((lambda_dbl[n] - max_val));

      T_partials_return dot_exp_lam_theta = dot_product(exp_lambda_dbl,
                                                        theta_dbl);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> theta_deriv(N, 1);
          theta_deriv = exp_lambda_dbl / dot_exp_lam_theta;

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> lam_deriv(N, 1);
        for (size_t n = 0; n < N; ++n)
          lam_deriv[n] = (exp_lambda_dbl[n] * theta_dbl[n]) / dot_exp_lam_theta;

      operands_and_partials<T_theta, T_lam> ops_partials(theta, lambda);
      if (!(is_constant_struct<T_theta>::value
                                && is_constant_struct<T_lam>::value)) {
        if (!is_constant_struct<T_theta>::value)
          ops_partials.edge1_.partials_ = theta_deriv;

        if (!is_constant_struct<T_lam>::value)
          ops_partials.edge2_.partials_ = lam_deriv;
      }

      return ops_partials.build(log_sum_exp(logp_tmp));
    }
  }
}
#endif
<commit_msg>Final tidying<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_LOG_MIX_HPP
#define STAN_MATH_PRIM_MAT_FUN_LOG_MIX_HPP

#include <stan/math/prim/scal/meta/partials_return_type.hpp>
#include <stan/math/prim/scal/meta/operands_and_partials.hpp>
#include <stan/math/prim/scal/meta/scalar_seq_view.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/prim/scal/err/check_bounded.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/mat/meta/is_constant_struct.hpp>
#include <stan/math/prim/mat/fun/log_sum_exp.hpp>
#include <stan/math/prim/mat/fun/log.hpp>
#include <stan/math/prim/mat/fun/exp.hpp>
#include <stan/math/prim/mat/fun/max.hpp>
#include <stan/math/prim/mat/fun/dot_product.hpp>
#include <stan/math/prim/mat/fun/value_of.hpp>
#include <stan/math/prim/mat/fun/value_of_rec.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <string>
#include <algorithm>

namespace stan {
  namespace math {

    /**
     * Return the log mixture density with specified mixing proportion
     * and log densities.
     *
     *
     * @param theta vector of mixing proportions in [0, 1].
     * @param lambda vector of log densities.
     * @return log mixture of densities in specified proportion
     */
    template <typename T_theta, typename T_lam>
    typename return_type<T_theta, T_lam>::type
    log_mix(const T_theta& theta,
            const T_lam& lambda) {
      static const std::string function = "log_mix";
    typedef typename stan::partials_return_type<T_theta, T_lam>::type
      T_partials_return;

      const size_t N = theta.size();

      for (size_t n = 0; n < N; ++n) {
        check_not_nan(function, "lambda", lambda[n]);
        check_not_nan(function, "theta", theta[n]);
        check_finite(function, "lambda", lambda[n]);
        check_finite(function, "theta", theta[n]);
        check_bounded(function, "theta", theta[n], 0, 1);
      }
      check_consistent_sizes(function, "theta", theta, "lambda", lambda);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> theta_dbl(N, 1);
      scalar_seq_view<T_theta> theta_vec(theta);
        for (size_t n = 0; n < N; ++n)
          theta_dbl[n] = value_of(theta_vec[n]);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> lambda_dbl(N, 1);
      scalar_seq_view<T_lam> lam_vec(lambda);
        for (size_t n = 0; n < N; ++n)
          lambda_dbl[n] = value_of(lam_vec[n]);

      /**
       * Vector containing log-prob of each density, log_sum_exp applied as
       * part of return call.
       */
      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> logp_tmp(N, 1);
        logp_tmp = log(theta_dbl) + lambda_dbl;

      /**
       * Calculate derivatives
       *
       * Exp-normalise to prevent overflow, as:
       * (exp(x-a) * exp(a)) / (exp(y-a) * exp(a)) = exp(x-a) / exp(y-a)
       */
      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> exp_lambda_dbl(N, 1);
      double max_val = max(lambda_dbl);
        for (size_t n = 0; n < N; ++n)
          exp_lambda_dbl[n] = exp((lambda_dbl[n] - max_val));

      T_partials_return dot_exp_lam_theta = dot_product(exp_lambda_dbl,
                                                        theta_dbl);

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> theta_deriv(N, 1);
          theta_deriv = exp_lambda_dbl / dot_exp_lam_theta;

      Eigen::Matrix<T_partials_return, Eigen::Dynamic, 1> lam_deriv(N, 1);
        for (size_t n = 0; n < N; ++n)
          lam_deriv[n] = (exp_lambda_dbl[n] * theta_dbl[n]) / dot_exp_lam_theta;

      operands_and_partials<T_theta, T_lam> ops_partials(theta, lambda);
      if (!(is_constant_struct<T_theta>::value
                                && is_constant_struct<T_lam>::value)) {
        if (!is_constant_struct<T_theta>::value)
          ops_partials.edge1_.partials_ = theta_deriv;

        if (!is_constant_struct<T_lam>::value)
          ops_partials.edge2_.partials_ = lam_deriv;
      }

      return ops_partials.build(log_sum_exp(logp_tmp));
    }
  }
}
#endif
<|endoftext|>


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

#if HAVE_CONFIG_H
#include <config.h>
#endif

#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTSUBSTORAGESUPPLIER_HPP_
#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#include "hsqldb/HStorageAccess.h"
#include "hsqldb/HStorageMap.hxx"
#include "hsqldb/StorageNativeInputStream.h"

#include "jvmaccess/virtualmachine.hxx"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"

#include <rtl/logfile.hxx>
#include <limits>

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::connectivity::hsqldb;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
/*****************************************************************************/
/* exception macros */

#define ThrowException(env, type, msg) { \
    env->ThrowNew(env->FindClass(type), msg); }
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    openStream
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_openStream
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jint mode)
{
#if OSL_DEBUG_LEVEL > 1
    {
        ::rtl::OUString sOrgName = StorageContainer::jstring2ustring(env,name);
        sOrgName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".input"));
        ::rtl::OString sName = ::rtl::OUStringToOString(sOrgName,RTL_TEXTENCODING_ASCII_US);
        getStreams()[sOrgName] = fopen( sName.getStr(), "a+" );
    }
#endif
    StorageContainer::registerStream(env,name,key,mode);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
    return Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2(env,obj_this,name,key);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3BII
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jbyteArray buffer, jint off, jint len)
{
    return Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII(env,obj_this,name,key,buffer,off,len);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    close
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_close
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    {
        ::rtl::OUString sOrgName = StorageContainer::jstring2ustring(env,name);
        sOrgName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".input"));
        fclose( getStreams()[sOrgName] );
        getStreams().erase(sOrgName);
    }
#endif
    StorageContainer::revokeStream(env,name,key);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    skip
 * Signature: (Ljava/lang/String;Ljava/lang/String;J)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_skip
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jlong n)
{
    if ( n < 0 )
        ThrowException( env,
                        "java/io/IOException",
                        "n < 0");

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    OSL_ENSURE(pHelper.get(),"No stream helper!");
    if ( pHelper.get() )
    {
        Reference<XInputStream> xIn = pHelper->getInputStream();
        if ( xIn.is() )
        {
            try
            {
                sal_Int64 nBytesSkipped = 0;
                sal_Int64 tmpLongVal = n;
                sal_Int32 tmpIntVal;

                try
                {
                    do {
                        if (tmpLongVal >= ::std::numeric_limits<sal_Int64>::max() )
                            tmpIntVal = ::std::numeric_limits<sal_Int32>::max();
                        else // Casting is safe here.
                            tmpIntVal = static_cast<sal_Int32>(tmpLongVal);

                        tmpLongVal -= tmpIntVal;

                        xIn->skipBytes(tmpIntVal);

                    } while (tmpLongVal > 0);
                }
                catch(Exception& e )
                {
                }

                return n - tmpLongVal;
            }
            catch(Exception& e)
            {
                OSL_ENSURE(0,"Exception catched! : skip();");
                StorageContainer::throwJavaException(e,env);
            }
        }
    }
    else
    {
        ThrowException( env,
                        "java/io/IOException",
                        "Stream is not valid");
    }
    return 0;
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    available
 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_available
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    OSL_ENSURE(pHelper.get(),"No stream helper!");
    Reference<XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference<XInputStream>();
    if ( xIn.is() )
    {
        try
        {
            return xIn->available();
        }
        catch(Exception& e)
        {
            OSL_ENSURE(0,"Exception catched! : available();");
            StorageContainer::throwJavaException(e,env);
        }
    }
    else
    {
        ThrowException( env,
                        "java/io/IOException",
                        "Stream is not valid");
    }
    return 0;
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;[B)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3B
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jbyteArray buffer)
{
    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>();
    OSL_ENSURE(xIn.is(),"Input stream is NULL!");
    sal_Int32 nBytesRead = 0;
    if ( xIn.is() )
    {
        jsize nLen = env->GetArrayLength(buffer);
        Sequence< ::sal_Int8 > aData(nLen);

        try
        {
            nBytesRead = xIn->readBytes(aData,nLen);
        }
        catch(Exception& e)
        {
            OSL_ENSURE(0,"Exception catched! : skip();");
            StorageContainer::throwJavaException(e,env);
        }

        // Casting bytesRead to an int is okay, since the user can
        // only pass in an integer length to read, so the bytesRead
        // must <= len.
        //
        if (nBytesRead <= 0) {
            return -1;
        }
        OSL_ENSURE(nLen >= nBytesRead,"Buffer is too small!");
        OSL_ENSURE(aData.getLength() >= nBytesRead,"Buffer is too small!");
        env->SetByteArrayRegion(buffer,0,nBytesRead,&aData[0]);
#if OSL_DEBUG_LEVEL > 1
        ::rtl::OUString sOrgName = StorageContainer::jstring2ustring(env,name);
        sOrgName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".input"));
        fwrite(&aData[0],sizeof(sal_Int8),nBytesRead,getStreams()[sOrgName]);
#endif
    }
    return nBytesRead;
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS dba28 (1.3.22); FILE MERGED 2005/03/30 11:27:29 fs 1.3.22.3: RESYNC: (1.3-1.4); FILE MERGED 2005/03/23 14:58:31 fs 1.3.22.2: #i45314# logging facilities 2005/03/21 12:53:33 fs 1.3.22.1: copying the changes from CWS dba26 herein, since they're needed to fix i45314<commit_after>/*************************************************************************
 *
 *  $RCSfile: StorageNativeInputStream.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-03-30 11:52:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Ocke Janssen
 *
 *
 ************************************************************************/

#if HAVE_CONFIG_H
#include <config.h>
#endif

#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTSUBSTORAGESUPPLIER_HPP_
#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef CONNECTIVITY_HSQLDB_STORAGEACCESS_HXX
#include "hsqldb/HStorageAccess.hxx"
#endif
#include "hsqldb/HStorageMap.hxx"
#include "hsqldb/StorageNativeInputStream.h"

#include "jvmaccess/virtualmachine.hxx"
#ifndef _COM_SUN_STAR_LANG_XSINGLECOMPONENTFACTORY_HPP_
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#endif

#ifndef CONNECTIVITY_HSQLDB_ACCESSLOG_HXX
#include "accesslog.hxx"
#endif

#include <limits>

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::connectivity::hsqldb;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
/*****************************************************************************/
/* exception macros */

#define ThrowException(env, type, msg) { \
    env->ThrowNew(env->FindClass(type), msg); }
/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    openStream
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_openStream
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jint mode)
{
#if OSL_DEBUG_LEVEL > 1
    {
        OperationLogFile( env, name, "input" ).logOperation( "openStream" );
        LogFile( env, name, "input" ).create();
    }
#endif
    StorageContainer::registerStream(env,name,key,mode);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "input" ).logOperation( "read()" );

    DataLogFile aDataLog( env, name, "input" );
    return read_from_storage_stream( env, obj_this, name, key, &aDataLog );
#else
    return read_from_storage_stream( env, obj_this, name, key );
#endif
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3BII
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jbyteArray buffer, jint off, jint len)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "input" ).logOperation( "read( byte[], int, int )" );

    DataLogFile aDataLog( env, name, "input" );
    return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog );
#else
    return read_from_storage_stream_into_buffer(env,obj_this,name,key,buffer,off,len);
#endif
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    close
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_close
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile aOpLog( env, name, "input" );
    aOpLog.logOperation( "close" );
    aOpLog.close();

    LogFile aDataLog( env, name, "input" );
    aDataLog.close();
#endif
    StorageContainer::revokeStream(env,name,key);
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    skip
 * Signature: (Ljava/lang/String;Ljava/lang/String;J)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_skip
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jlong n)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile( env, name, "input" ).logOperation( "skip()" );
#endif

    if ( n < 0 )
        ThrowException( env,
                        "java/io/IOException",
                        "n < 0");

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    OSL_ENSURE(pHelper.get(),"No stream helper!");
    if ( pHelper.get() )
    {
        Reference<XInputStream> xIn = pHelper->getInputStream();
        if ( xIn.is() )
        {
            try
            {
                sal_Int64 nBytesSkipped = 0;
                sal_Int64 tmpLongVal = n;
                sal_Int32 tmpIntVal;

                try
                {
                    do {
                        if (tmpLongVal >= ::std::numeric_limits<sal_Int64>::max() )
                            tmpIntVal = ::std::numeric_limits<sal_Int32>::max();
                        else // Casting is safe here.
                            tmpIntVal = static_cast<sal_Int32>(tmpLongVal);

                        tmpLongVal -= tmpIntVal;

                        xIn->skipBytes(tmpIntVal);

                    } while (tmpLongVal > 0);
                }
                catch(Exception& e )
                {
                }

                return n - tmpLongVal;
            }
            catch(Exception& e)
            {
                OSL_ENSURE(0,"Exception catched! : skip();");
                StorageContainer::throwJavaException(e,env);
            }
        }
    }
    else
    {
        ThrowException( env,
                        "java/io/IOException",
                        "Stream is not valid");
    }
    return 0;
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    available
 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_available
  (JNIEnv * env, jobject obj_this,jstring key, jstring name)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile aOpLog( env, name, "input" );
    aOpLog.logOperation( "available" );
#endif

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    OSL_ENSURE(pHelper.get(),"No stream helper!");
    Reference<XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference<XInputStream>();
    if ( xIn.is() )
    {
        try
        {
            jint nAvailable = xIn->available();
#if OSL_DEBUG_LEVEL > 1
            aOpLog.logReturn( nAvailable );
#endif
            return nAvailable;
        }
        catch(Exception& e)
        {
            OSL_ENSURE(0,"Exception catched! : available();");
            StorageContainer::throwJavaException(e,env);
        }
    }
    else
    {
        ThrowException( env,
                        "java/io/IOException",
                        "Stream is not valid");
    }
    return 0;
}
// -----------------------------------------------------------------------------

/*
 * Class:     com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream
 * Method:    read
 * Signature: (Ljava/lang/String;Ljava/lang/String;[B)I
 */
JNIEXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3B
  (JNIEnv * env, jobject obj_this,jstring key, jstring name, jbyteArray buffer)
{
#if OSL_DEBUG_LEVEL > 1
    OperationLogFile aOpLog( env, name, "input" );
    aOpLog.logOperation( "read( byte[] )" );

    DataLogFile aDataLog( env, name, "input" );
#endif

    ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
    Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>();
    OSL_ENSURE(xIn.is(),"Input stream is NULL!");
    jint nBytesRead = 0;
    if ( xIn.is() )
    {
        jsize nLen = env->GetArrayLength(buffer);
        Sequence< ::sal_Int8 > aData(nLen);

        try
        {
            nBytesRead = xIn->readBytes(aData,nLen);
        }
        catch(Exception& e)
        {
            OSL_ENSURE(0,"Exception catched! : skip();");
            StorageContainer::throwJavaException(e,env);
        }

        // Casting bytesRead to an int is okay, since the user can
        // only pass in an integer length to read, so the bytesRead
        // must <= len.
        //
        if (nBytesRead <= 0) {
#if OSL_DEBUG_LEVEL > 1
            aOpLog.logReturn( (jint)-1 );
#endif
            return -1;
        }
        OSL_ENSURE(nLen >= nBytesRead,"Buffer is too small!");
        OSL_ENSURE(aData.getLength() >= nBytesRead,"Buffer is too small!");
        env->SetByteArrayRegion(buffer,0,nBytesRead,&aData[0]);
#if OSL_DEBUG_LEVEL > 1
        aDataLog.write( &aData[0], nBytesRead );
#endif
    }
#if OSL_DEBUG_LEVEL > 1
    aOpLog.logReturn( nBytesRead );
#endif
    return nBytesRead;
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before><commit_msg>fix tree by commenting out histograms<commit_after><|endoftext|>