<commit_before>/* -------------------------------------------------------------------------- *
 *                     OpenSim:  CMCActuatorSubsystem.cpp                     *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */
#include "CMCActuatorSubsystem.h"
#include <OpenSim/Common/FunctionSet.h>
#include <OpenSim/Simulation/Model/Model.h>
using namespace OpenSim;
using namespace SimTK;
using namespace std;

void CMCActuatorSubsystemRep::setCompleteState(const SimTK::State& state) {
    _completeState = state;
}
const SimTK::State& CMCActuatorSubsystemRep::getCompleteState() const{
    return(_completeState);
}
FunctionSet* CMCActuatorSubsystemRep::getCoordinateTrajectories() const {
   return( _qSet);
}
FunctionSet* CMCActuatorSubsystemRep::getSpeedTrajectories() const {
   return( _uSet);
}

void CMCActuatorSubsystemRep::setCoordinateCorrections(const double* aCorrections) {
    int i ;
    int size = _qCorrections.getSize();
    for(i=0;i<size;i++) {
         _qCorrections[i] = aCorrections[i];
    }

}

void CMCActuatorSubsystemRep::setSpeedCorrections(const double* aCorrections) {
    int i ;
    int size = _uCorrections.getSize();
    for(i=0;i<size;i++) {
         _uCorrections[i] = aCorrections[i];
    }
}

void CMCActuatorSubsystemRep::setCoordinateTrajectories(FunctionSet *aSet) {
    // ERROR CHECKING
    if(aSet == NULL) {
        string msg = "CMCActuatorSubsystemRep.setCoordinateTrajectories:";
        msg += " ERR- NULL function set.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }
    if(aSet->getSize() != _model->getNumCoordinates()) {
        string msg = "CMCActuatorSubsystemRep.setCoordinateTrajectories:";
        msg += " ERR- incorrect number of trajectories.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }

    _qSet = aSet;
}
void CMCActuatorSubsystemRep::setSpeedTrajectories(FunctionSet *aSet) {
    // ERROR CHECKING
    if(aSet == NULL) {
        string msg = "CMCActuatorSubsystemRep.setSpeedTrajectories:";
        msg += " ERR- NULL function set.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }
    if(aSet->getSize() != _model->getNumSpeeds()) {
        string msg = "CMCActuatorSubsystemRep.setSpeedTrajectories:";
        msg += " ERR- incorrect number of trajectories.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }

    _uSet = aSet;
}
   CMCActuatorSubsystemRep::CMCActuatorSubsystemRep(Model* model)
       : SimTK::Subsystem::Guts( "CMCActuatorSubsystem", "2.0"),
       _model(model),
       _holdCoordinatesConstant(false),
       _holdTime(0.0),
       _qSet(NULL),
       _uSet(NULL) {

       _qCorrections.setSize(_model->getNumCoordinates() );
       _uCorrections.setSize(_model->getNumSpeeds() );
       _qWork.setSize(_model->getNumCoordinates());
       _uWork.setSize(_model->getNumSpeeds());
   }
   CMCActuatorSubsystemRep* CMCActuatorSubsystemRep::cloneImpl() const { return new CMCActuatorSubsystemRep(*this); }

  CMCActuatorSubsystemRep::~CMCActuatorSubsystemRep() { }

  int CMCActuatorSubsystemRep::realizeSubsystemTopologyImpl(State& s) const {
     // Make sure the CMC Actuator subsystem has the same number of Z's as
     // the model as a whole so we don't miss any of them. This will include
     // some that aren't muscle states, but who cares?
     Vector z(_model->getMultibodySystem().getDefaultState().getNZ());
     s.allocateZ( getMySubsystemIndex(), z );
     return 0;
  }
  void CMCActuatorSubsystemRep::holdCoordinatesConstant( double t ) {
      _holdCoordinatesConstant = true;
      _holdTime = t;
  }
  void CMCActuatorSubsystemRep::releaseCoordinates() {
       _holdCoordinatesConstant = false;
  }
  Model*  CMCActuatorSubsystemRep::getModel() const {
       return( _model);
  }

  int CMCActuatorSubsystemRep::realizeSubsystemDynamicsImpl(const State& s) const
  {
     /* set generalized coordinates and speeds from spline sets */
    int nq = _model->getNumCoordinates();
    double t;

    if(_holdCoordinatesConstant) {
         t = _holdTime;
    } else  {
         t = s.getTime();
    }

    _qSet->evaluate(_qWork,0,t);
    if(_uSet!=NULL) {
        _uSet->evaluate(_uWork,0,t);
    } else {
        _qSet->evaluate(_uWork,1,t);
    }

    /* Hack to obtain a mutable state in a const method */
    State& mutableCompState = const_cast<SimTK::State&>(_completeState);

    // Update the coordinate values to pose the model while computing muscle
    // controls
    const CoordinateSet& coords = _model->getCoordinateSet();
    for (int i = 0; i < nq; ++i) {
        // the last argument to setValue, a bool to enforce constraints,
        // is false since values come from a _qSet of splined desired
        // kinematics formed from formCompleteStorages, which enforces
        // model constraints.
        coords[i].setValue(mutableCompState, _qWork[i] + _qCorrections[i], false);
        coords[i].setSpeedValue(mutableCompState, _uWork[i] + _uCorrections[i]);
    }
    // projectQ is sufficient to satisfy constraints perturbed by _qCorrections
    _model->getMultibodySystem().projectQ(mutableCompState,
        getModel()->get_assembly_accuracy()/10);

     /* copy  muscle states computed from the actuator system to the muscle states
        for the complete system  then compute forces*/
    mutableCompState.updZ() = s.getZ();
    mutableCompState.updTime() = t;

     _model->getMultibodySystem().realize(_completeState, SimTK::Stage::Acceleration);

     /* copy 1st derivatives of muscle states from complete system to actuator system */
     s.updZDot() = _completeState.getZDot();

/*
    cout << "_qWork=" << _qWork << endl;
    cout << "_uWork=" << _uWork << endl;
    cout << "actuatorStates=" << s.getZ() << endl;
    cout << " CMCrealize:Dynamics  time=" <<  s.getTime();
    cout << " Actuator dydt=" << _completeState.getZDot() << endl;

*/
     return 0;
  }

   CMCActuatorSubsystem::CMCActuatorSubsystem(CMCActuatorSystem& system, Model* model) {
       adoptSubsystemGuts( rep = new CMCActuatorSubsystemRep(model) );
       system.adoptSubsystem( *this );
   }
   void CMCActuatorSubsystem::holdCoordinatesConstant( double t ) {
       rep->holdCoordinatesConstant(t);
   }
   void CMCActuatorSubsystem::releaseCoordinates() {
       rep->releaseCoordinates();
   }
<commit_msg>Project Us as well as Qs for correctness.<commit_after>/* -------------------------------------------------------------------------- *
 *                     OpenSim:  CMCActuatorSubsystem.cpp                     *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */
#include "CMCActuatorSubsystem.h"
#include <OpenSim/Common/FunctionSet.h>
#include <OpenSim/Simulation/Model/Model.h>
using namespace OpenSim;
using namespace SimTK;
using namespace std;

void CMCActuatorSubsystemRep::setCompleteState(const SimTK::State& state) {
    _completeState = state;
}
const SimTK::State& CMCActuatorSubsystemRep::getCompleteState() const{
    return(_completeState);
}
FunctionSet* CMCActuatorSubsystemRep::getCoordinateTrajectories() const {
   return( _qSet);
}
FunctionSet* CMCActuatorSubsystemRep::getSpeedTrajectories() const {
   return( _uSet);
}

void CMCActuatorSubsystemRep::setCoordinateCorrections(const double* aCorrections) {
    int i ;
    int size = _qCorrections.getSize();
    for(i=0;i<size;i++) {
         _qCorrections[i] = aCorrections[i];
    }

}

void CMCActuatorSubsystemRep::setSpeedCorrections(const double* aCorrections) {
    int i ;
    int size = _uCorrections.getSize();
    for(i=0;i<size;i++) {
         _uCorrections[i] = aCorrections[i];
    }
}

void CMCActuatorSubsystemRep::setCoordinateTrajectories(FunctionSet *aSet) {
    // ERROR CHECKING
    if(aSet == NULL) {
        string msg = "CMCActuatorSubsystemRep.setCoordinateTrajectories:";
        msg += " ERR- NULL function set.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }
    if(aSet->getSize() != _model->getNumCoordinates()) {
        string msg = "CMCActuatorSubsystemRep.setCoordinateTrajectories:";
        msg += " ERR- incorrect number of trajectories.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }

    _qSet = aSet;
}
void CMCActuatorSubsystemRep::setSpeedTrajectories(FunctionSet *aSet) {
    // ERROR CHECKING
    if(aSet == NULL) {
        string msg = "CMCActuatorSubsystemRep.setSpeedTrajectories:";
        msg += " ERR- NULL function set.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }
    if(aSet->getSize() != _model->getNumSpeeds()) {
        string msg = "CMCActuatorSubsystemRep.setSpeedTrajectories:";
        msg += " ERR- incorrect number of trajectories.\n";
        throw( Exception(msg,__FILE__,__LINE__) );
    }

    _uSet = aSet;
}
   CMCActuatorSubsystemRep::CMCActuatorSubsystemRep(Model* model)
       : SimTK::Subsystem::Guts( "CMCActuatorSubsystem", "2.0"),
       _model(model),
       _holdCoordinatesConstant(false),
       _holdTime(0.0),
       _qSet(NULL),
       _uSet(NULL) {

       _qCorrections.setSize(_model->getNumCoordinates() );
       _uCorrections.setSize(_model->getNumSpeeds() );
       _qWork.setSize(_model->getNumCoordinates());
       _uWork.setSize(_model->getNumSpeeds());
   }
   CMCActuatorSubsystemRep* CMCActuatorSubsystemRep::cloneImpl() const { return new CMCActuatorSubsystemRep(*this); }

  CMCActuatorSubsystemRep::~CMCActuatorSubsystemRep() { }

  int CMCActuatorSubsystemRep::realizeSubsystemTopologyImpl(State& s) const {
     // Make sure the CMC Actuator subsystem has the same number of Z's as
     // the model as a whole so we don't miss any of them. This will include
     // some that aren't muscle states, but who cares?
     Vector z(_model->getMultibodySystem().getDefaultState().getNZ());
     s.allocateZ( getMySubsystemIndex(), z );
     return 0;
  }
  void CMCActuatorSubsystemRep::holdCoordinatesConstant( double t ) {
      _holdCoordinatesConstant = true;
      _holdTime = t;
  }
  void CMCActuatorSubsystemRep::releaseCoordinates() {
       _holdCoordinatesConstant = false;
  }
  Model*  CMCActuatorSubsystemRep::getModel() const {
       return( _model);
  }

  int CMCActuatorSubsystemRep::realizeSubsystemDynamicsImpl(const State& s) const
  {
     /* set generalized coordinates and speeds from spline sets */
    int nq = _model->getNumCoordinates();
    double t;

    if(_holdCoordinatesConstant) {
         t = _holdTime;
    } else  {
         t = s.getTime();
    }

    _qSet->evaluate(_qWork,0,t);
    if(_uSet!=NULL) {
        _uSet->evaluate(_uWork,0,t);
    } else {
        _qSet->evaluate(_uWork,1,t);
    }

    /* Hack to obtain a mutable state in a const method */
    State& mutableCompState = const_cast<SimTK::State&>(_completeState);

    // Update the coordinate values to pose the model while computing muscle
    // controls
    const CoordinateSet& coords = _model->getCoordinateSet();
    for (int i = 0; i < nq; ++i) {
        // the last argument to setValue, a bool to enforce constraints,
        // is false since values come from a _qSet of splined desired
        // kinematics formed from formCompleteStorages, which enforces
        // model constraints.
        coords[i].setValue(mutableCompState, _qWork[i] + _qCorrections[i], false);
        coords[i].setSpeedValue(mutableCompState, _uWork[i] + _uCorrections[i]);
    }
    // project() to satisfy constraints perturbed by _q/_uCorrections
    _model->getMultibodySystem().projectQ(mutableCompState,
        getModel()->get_assembly_accuracy() / 10);
    _model->getMultibodySystem().projectU(mutableCompState,
        getModel()->get_assembly_accuracy() / 10);

    /* copy  muscle states computed from the actuator system to the muscle states
       for the complete system  then compute forces*/
    mutableCompState.updZ() = s.getZ();
    mutableCompState.updTime() = t;

    _model->getMultibodySystem().realize(_completeState, SimTK::Stage::Acceleration);

    /* copy 1st derivatives of muscle states from complete system to actuator system */
    s.updZDot() = _completeState.getZDot();

/*
    cout << "_qWork=" << _qWork << endl;
    cout << "_uWork=" << _uWork << endl;
    cout << "actuatorStates=" << s.getZ() << endl;
    cout << " CMCrealize:Dynamics  time=" <<  s.getTime();
    cout << " Actuator dydt=" << _completeState.getZDot() << endl;

*/
     return 0;
  }

   CMCActuatorSubsystem::CMCActuatorSubsystem(CMCActuatorSystem& system, Model* model) {
       adoptSubsystemGuts( rep = new CMCActuatorSubsystemRep(model) );
       system.adoptSubsystem( *this );
   }
   void CMCActuatorSubsystem::holdCoordinatesConstant( double t ) {
       rep->holdCoordinatesConstant(t);
   }
   void CMCActuatorSubsystem::releaseCoordinates() {
       rep->releaseCoordinates();
   }
<|endoftext|>


<commit_before>// Copyright 1999-2005 The RE2 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 <stdio.h>
#include "re2/util/util.h"
#include "re2/stringpiece.h"

namespace re2 {

// ----------------------------------------------------------------------
// CEscapeString()
//    Copies 'src' to 'dest', escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
//    Returns the number of bytes written to 'dest' (not including the \0)
//    or -1 if there was insufficient space.
// ----------------------------------------------------------------------
int CEscapeString(const char* src, int src_len, char* dest,
                  int dest_len) {
  const char* src_end = src + src_len;
  int used = 0;

  for (; src < src_end; src++) {
    if (dest_len - used < 2)   // space for two-character escape
      return -1;

    unsigned char c = *src;
    switch (c) {
      case '\n': dest[used++] = '\\'; dest[used++] = 'n';  break;
      case '\r': dest[used++] = '\\'; dest[used++] = 'r';  break;
      case '\t': dest[used++] = '\\'; dest[used++] = 't';  break;
      case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
      case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
      case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
      default:
        // Note that if we emit \xNN and the src character after that is a hex
        // digit then that digit must be escaped too to prevent it being
        // interpreted as part of the character code by C.
        if (c < ' ' || c > '~') {
          if (dest_len - used < 5)   // space for four-character escape + \0
            return -1;
		  #ifdef WIN32
		  sprintf_s(dest + used, dest_len, "\\%03o", c);
		  #else
		  std::sprintf(dest + used, "\\%03o", c);
		  #endif

          used += 4;
        } else {
          dest[used++] = c; break;
        }
    }
  }

  if (dest_len - used < 1)   // make sure that there is room for \0
    return -1;

  dest[used] = '\0';   // doesn't count towards return value though
  return used;
}

// ----------------------------------------------------------------------
// CEscape()
//    Copies 'src' to result, escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
// ----------------------------------------------------------------------
string CEscape(const StringPiece& src) {
  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
  char* dest = new char[dest_length];
  const int len = CEscapeString(src.data(), src.size(),
                                dest, dest_length);
  string s = string(dest, len);
  delete[] dest;
  return s;
}

string PrefixSuccessor(const StringPiece& prefix) {
  // We can increment the last character in the string and be done
  // unless that character is 255, in which case we have to erase the
  // last character and increment the previous character, unless that
  // is 255, etc. If the string is empty or consists entirely of
  // 255's, we just return the empty string.
  bool done = false;
  string limit(prefix.data(), prefix.size());
  int index = limit.length() - 1;
  while (!done && index >= 0) {
    if ((limit[index]&255) == 255) {
      limit.erase(index);
      index--;
    } else {
      limit[index]++;
      done = true;
    }
  }
  if (!done) {
    return "";
  } else {
    return limit;
  }
}

}  // namespace re2
<commit_msg>Removed accidental std:: prefix<commit_after>// Copyright 1999-2005 The RE2 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 "re2/util/util.h"
#include "re2/stringpiece.h"

namespace re2 {

// ----------------------------------------------------------------------
// CEscapeString()
//    Copies 'src' to 'dest', escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
//    Returns the number of bytes written to 'dest' (not including the \0)
//    or -1 if there was insufficient space.
// ----------------------------------------------------------------------
int CEscapeString(const char* src, int src_len, char* dest,
                  int dest_len) {
  const char* src_end = src + src_len;
  int used = 0;

  for (; src < src_end; src++) {
    if (dest_len - used < 2)   // space for two-character escape
      return -1;

    unsigned char c = *src;
    switch (c) {
      case '\n': dest[used++] = '\\'; dest[used++] = 'n';  break;
      case '\r': dest[used++] = '\\'; dest[used++] = 'r';  break;
      case '\t': dest[used++] = '\\'; dest[used++] = 't';  break;
      case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
      case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
      case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
      default:
        // Note that if we emit \xNN and the src character after that is a hex
        // digit then that digit must be escaped too to prevent it being
        // interpreted as part of the character code by C.
        if (c < ' ' || c > '~') {
          if (dest_len - used < 5)   // space for four-character escape + \0
            return -1;
		  #ifdef WIN32
		  sprintf_s(dest + used, dest_len, "\\%03o", c);
		  #else
		  sprintf(dest + used, "\\%03o", c);
		  #endif

          used += 4;
        } else {
          dest[used++] = c; break;
        }
    }
  }

  if (dest_len - used < 1)   // make sure that there is room for \0
    return -1;

  dest[used] = '\0';   // doesn't count towards return value though
  return used;
}

// ----------------------------------------------------------------------
// CEscape()
//    Copies 'src' to result, escaping dangerous characters using
//    C-style escape sequences.  'src' and 'dest' should not overlap.
// ----------------------------------------------------------------------
string CEscape(const StringPiece& src) {
  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
  char* dest = new char[dest_length];
  const int len = CEscapeString(src.data(), src.size(),
                                dest, dest_length);
  string s = string(dest, len);
  delete[] dest;
  return s;
}

string PrefixSuccessor(const StringPiece& prefix) {
  // We can increment the last character in the string and be done
  // unless that character is 255, in which case we have to erase the
  // last character and increment the previous character, unless that
  // is 255, etc. If the string is empty or consists entirely of
  // 255's, we just return the empty string.
  bool done = false;
  string limit(prefix.data(), prefix.size());
  int index = limit.length() - 1;
  while (!done && index >= 0) {
    if ((limit[index]&255) == 255) {
      limit.erase(index);
      index--;
    } else {
      limit[index]++;
      done = true;
    }
  }
  if (!done) {
    return "";
  } else {
    return limit;
  }
}

}  // namespace re2
<|endoftext|>


<commit_before>// THIS FILE IS AUTO GENERATED, EDIT AT YOUR OWN RISK
//% L

#include "{{files['declaration']}}"
#include "{{files['entities']}}"
#include <tuple>

//% L

#define myoffsetof(st, m) static_cast<int>((size_t)(&((st *)0)->m))

//% L
// Implementation of the base entity class
//% L

//* Constructor of entity
Entity::Entity(const MessageHandler *messageHandlers, const int* componentOffsets
    {% for attrib in general.common_entity_attributes %}
        ,{{attrib.get_declaration()}}
    {% endfor %}
): messageHandlers(messageHandlers), componentOffsets(componentOffsets)
    {% for attrib in general.common_entity_attributes %}
        ,{{attrib.get_initializer()}}
    {% endfor %}
{
}

//% L

Entity::~Entity() {
}

//% L

bool Entity::SendMessage(int msg, const void* data) {
    MessageHandler handler = messageHandlers[msg];
    if (handler) {
        handler(this, data);
        return true;
    }
    return false;
}

//% L
//* Entity helper functions to send message e.g.
//*   void Entity::Damage(int value);
{% for message in messages %}
    bool Entity::{{message.name}}({{message.get_function_args()}}) {
        {% if message.get_num_args() == 0 %}
            return SendMessage({{message.get_enum_name()}}, nullptr);
        {% else %}
            {{message.get_tuple_type()}} data({{message.get_args_names()}});
            return SendMessage({{message.get_enum_name()}}, &data);
        {% endif %}
    }
{% endfor %}

//% L
// Implementation of the entities
//% L

{% for entity in entities %}

    //% L
    // Implementation of {{entity.get_type_name()}}
    //% L

    //* The vtable of offset of components in an entity
    //* TODO: doesn't handle component inheritance?
    const int {{entity.get_type_name()}}::componentOffsets[] = {
        {% for component in components %}
            {% if component in entity.get_components() %}
                myoffsetof({{entity.get_type_name()}}, {{component.get_variable_name()}}),
            {% else %}
                0,
            {% endif %}
        {% endfor %}
    };

    //% L

    //* The static message handlers put in the vtable
    {% for message in entity.get_messages_to_handle() %}
        void {{entity.get_message_handler_name(message)}}(Entity* _entity, const void* {% if message.get_num_args() > 0 %} _data {% endif %} ) {
            //* Cast the entity to the correct type (receive an Entity*)
            {{entity.get_type_name()}}* entity = ({{entity.get_type_name()}}*) _entity;

            //% L

            {% if message.get_num_args() == 0 %}
                //* No argument for the message, just call the handlers of all the components
                {% for component in entity.get_components() %}
                    {% if message in component.get_messages_to_handle() %}
                        entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}();
                    {% endif %}
                {% endfor %}
            {% else %}
                //* Cast the message content to the right type (receive a const void*)
                const {{message.get_tuple_type()}}* data = (const {{message.get_tuple_type()}}*) _data;
                {% for component in entity.get_components() %}
                    {% if message in component.get_messages_to_handle() %}
                        entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}({{message.get_unpacked_tuple_args('*data')}});
                    {% endif %}
                {% endfor %}
            {% endif %}
        }
    {% endfor%}

    //% L

    //* The vtable of message handlers for an entity
    const MessageHandler {{entity.get_type_name()}}::messageHandlers[] = {
        {% for message in messages %}
            {% if message in entity.get_messages_to_handle() %}
                {{entity.get_message_handler_name(message)}},
            {% else %}
                nullptr,
            {% endif %}
        {% endfor%}
    };

    //% L

    //* Fat constructor for the entity that initializes the components.
    {{entity.get_type_name()}}::{{entity.get_type_name()}}(
        {% for (i, attrib) in enumerate(general.common_entity_attributes) %}
            {% if i != 0 %}, {% endif %} {{attrib.get_declaration()}}
        {% endfor %}
    ): Entity(messageHandlers, componentOffsets
        {% for attrib in general.common_entity_attributes %}
            ,{{attrib.get_name()}}
        {% endfor %}
    )
    {% for component in entity.get_components() %}
        //* Each component takes the entity it is in, its parameters and the components it requires
        , {{component.get_variable_name()}}(
            *this
            {% for param in component.get_param_names() %}
                , {{entity.get_params()[component.name][param]}}
            {% endfor %}
            {% for required in component.get_required_components() %}
                , *{{required.get_variable_name()}}
            {% endfor %}
        )
    {% endfor %}
    {}

    //% L

    //* The destructor of the entity destroys all the components in reverse order
    {{entity.get_type_name()}}::~{{entity.get_type_name()}}() {
    }
    //% L
{% endfor %}

//% L

#undef myoffsetof

<commit_msg>Prettify Components.cpp output file.<commit_after>// THIS FILE IS AUTO GENERATED, EDIT AT YOUR OWN RISK
//%L
#include "{{files['declaration']}}"
#include "{{files['entities']}}"
#include <tuple>
//%L
#define myoffsetof(st, m) static_cast<int>((size_t)(&((st *)0)->m))
//%L
// /////////// //
// Base entity //
// /////////// //
//%L
// Base entity constructor.
Entity::Entity(const MessageHandler *messageHandlers, const int* componentOffsets{% for attrib in general.common_entity_attributes %}, {{attrib.get_declaration()}}{% endfor %})
	: messageHandlers(messageHandlers), componentOffsets(componentOffsets){% for attrib in general.common_entity_attributes %}, {{attrib.get_initializer()}}{% endfor %}
{}
//%L
// Base entity deconstructor.
Entity::~Entity()
{}
//%L
// Base entity's message dispatcher.
bool Entity::SendMessage(int msg, const void* data) {
	MessageHandler handler = messageHandlers[msg];
	if (handler) {
		handler(this, data);
		return true;
	}
	return false;
}
//%L
// /////////////// //
// Message helpers //
// /////////////// //
//%L
{% for message in messages %}
bool Entity::{{message.name}}({{message.get_function_args()}}) {
	{% if message.get_num_args() == 0 %}
	return SendMessage({{message.get_enum_name()}}, nullptr);
	{% else %}
	{{message.get_tuple_type()}} data({{message.get_args_names()}});
	return SendMessage({{message.get_enum_name()}}, &data);
	{% endif %}
}
//%L
{% endfor %}
// ////////////////////// //
// Entity implementations //
// ////////////////////// //
//%L
{% for entity in entities %}
// {{entity.get_type_name()}}'s component offset vtable.
//* TODO: doesn't handle component inheritance?
const int {{entity.get_type_name()}}::componentOffsets[] = {
	{% for component in components %}
	{% if component in entity.get_components() %}
	myoffsetof({{entity.get_type_name()}}, {{component.get_variable_name()}}),
	{% else %}
	0,
	{% endif %}
	{% endfor %}
};
//%L
{% for message in entity.get_messages_to_handle() %}
// {{entity.get_type_name()}}'s {{message.get_name()}} message dispatcher.
void {{entity.get_message_handler_name(message)}}(Entity* _entity, const void* {% if message.get_num_args() > 0 %} _data{% endif %}) {
	//* Cast the entity to the correct type (receive an Entity*)
	{{entity.get_type_name()}}* entity = ({{entity.get_type_name()}}*) _entity;
	//%L
	{% if message.get_num_args() == 0 %}
	//* No argument for the message, just call the handlers of all the components
	{% for component in entity.get_components() %}
	{% if message in component.get_messages_to_handle() %}
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}();
	{% endif %}
	{% endfor %}
	{% else %}
	//* Cast the message content to the right type (receive a const void*)
	const {{message.get_tuple_type()}}* data = (const {{message.get_tuple_type()}}*) _data;
	{% for component in entity.get_components() %}
	{% if message in component.get_messages_to_handle() %}
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}({{message.get_unpacked_tuple_args('*data')}});
	{% endif %}
	{% endfor %}
	{% endif %}
}
//%L
{% endfor%}
// {{entity.get_type_name()}}'s message dispatcher vtable.
const MessageHandler {{entity.get_type_name()}}::messageHandlers[] = {
	{% for message in messages %}
	{% if message in entity.get_messages_to_handle() %}
	{{entity.get_message_handler_name(message)}},
	{% else %}
	nullptr,
	{% endif %}
	{% endfor%}
};
//%L
// {{entity.get_type_name()}}'s constructor.
{{entity.get_type_name()}}::{{entity.get_type_name()}}({% for (i, attrib) in enumerate(general.common_entity_attributes) %}{% if i != 0 %}, {% endif %} {{attrib.get_declaration()}}{% endfor %})
	: Entity(messageHandlers, componentOffsets{% for attrib in general.common_entity_attributes %}, {{attrib.get_name()}}{% endfor %})
	{% for component in entity.get_components() %}
	, {{component.get_variable_name()}}(*this{% for param in component.get_param_names() %}, {{entity.get_params()[component.name][param]}}{% endfor %}{% for required in component.get_required_components() %}, *{{required.get_variable_name()}}{% endfor %}){% endfor %}
{}
//%L
// {{entity.get_type_name()}}'s deconstructor.
//* Destroys all the components in reverse order.
{{entity.get_type_name()}}::~{{entity.get_type_name()}}()
{}
{% endfor %}
//%L
#undef myoffsetof

<|endoftext|>


<commit_before>// (C) 2013 Cybozu.

#include "ip_address.hpp"
#include "util.hpp"

#include <ifaddrs.h>
#include <cstring>
#include <netinet/in.h>
#include <sys/types.h>
#include <cerrno>

namespace {

class ifaddrs_wrapper {
    struct ifaddrs* m_addr;
public:
    ifaddrs_wrapper() {
        if( getifaddrs(&m_addr) != 0 )
            cybozu::throw_unix_error(errno, "getifaddrs");
    }
    ~ifaddrs_wrapper() {
        freeifaddrs(m_addr);
    }

    bool find(const cybozu::ip_address& addr) const {
        for(auto a = m_addr; a != nullptr; a = a->ifa_next) {
            if( a->ifa_addr == NULL ) continue;
            switch(a->ifa_addr->sa_family) {
            case AF_INET:
            case AF_INET6:
                if( addr == cybozu::ip_address(a->ifa_addr) )
                    return true;
            }
        }
        return false;
    }
};

} // anonymous namespace

namespace cybozu {

void ip_address::parse(const std::string& s) {
    if( inet_pton(AF_INET, s.c_str(), &addr) == 1 ) {
        af = addr_family::ipv4;
        return;
    }
    if( inet_pton(AF_INET6, s.c_str(), &addr) == 1 ) {
        af = addr_family::ipv6;
        return;
    }
    throw bad_address("Invalid address: " + s);
}

ip_address::ip_address(const std::string& s) {
    parse(s);
}

ip_address::ip_address(const struct sockaddr* ifa_addr) {
    if( ifa_addr->sa_family == AF_INET ) {
        af = addr_family::ipv4;
        const struct sockaddr_in* p = (const struct sockaddr_in*)ifa_addr;
        std::memcpy(&addr, &(p->sin_addr), sizeof(struct in_addr));
        return;
    }
    if( ifa_addr->sa_family == AF_INET6 ) {
        af = addr_family::ipv6;
        const struct sockaddr_in6* p = (const struct sockaddr_in6*)ifa_addr;
        std::memcpy(&addr, &(p->sin6_addr), sizeof(struct in6_addr));
        return;
    }
    throw bad_address("Invalid address family");
}

bool ip_address::operator==(const ip_address& rhs) const {
    if( af != rhs.af ) return false;
    if( is_v4() ) {
        return std::memcmp(v4addr(), rhs.v4addr(), sizeof(struct in_addr)) == 0;
    }
    return std::memcmp(v6addr(), rhs.v6addr(), sizeof(struct in6_addr)) == 0;
}

std::string ip_address::str() const {
    if( is_v4() ) {
        char dst[INET_ADDRSTRLEN];
        return std::string(inet_ntop(AF_INET, v4addr(), dst, INET_ADDRSTRLEN));
    }
    char dst[INET6_ADDRSTRLEN];
    return std::string(inet_ntop(AF_INET6, v6addr(), dst, INET6_ADDRSTRLEN));
}

bool has_ip_address(const ip_address& addr) {
    ifaddrs_wrapper ifw;
    return ifw.find(addr);
}

} // namespace cybozu
<commit_msg>check addr_family::none<commit_after>// (C) 2013 Cybozu.

#include "ip_address.hpp"
#include "util.hpp"

#include <ifaddrs.h>
#include <cstring>
#include <netinet/in.h>
#include <sys/types.h>
#include <cerrno>

namespace {

class ifaddrs_wrapper {
    struct ifaddrs* m_addr;
public:
    ifaddrs_wrapper() {
        if( getifaddrs(&m_addr) != 0 )
            cybozu::throw_unix_error(errno, "getifaddrs");
    }
    ~ifaddrs_wrapper() {
        freeifaddrs(m_addr);
    }

    bool find(const cybozu::ip_address& addr) const {
        for(auto a = m_addr; a != nullptr; a = a->ifa_next) {
            if( a->ifa_addr == NULL ) continue;
            switch(a->ifa_addr->sa_family) {
            case AF_INET:
            case AF_INET6:
                if( addr == cybozu::ip_address(a->ifa_addr) )
                    return true;
            }
        }
        return false;
    }
};

} // anonymous namespace

namespace cybozu {

void ip_address::parse(const std::string& s) {
    if( inet_pton(AF_INET, s.c_str(), &addr) == 1 ) {
        af = addr_family::ipv4;
        return;
    }
    if( inet_pton(AF_INET6, s.c_str(), &addr) == 1 ) {
        af = addr_family::ipv6;
        return;
    }
    throw bad_address("Invalid address: " + s);
}

ip_address::ip_address(const std::string& s) {
    parse(s);
}

ip_address::ip_address(const struct sockaddr* ifa_addr) {
    if( ifa_addr->sa_family == AF_INET ) {
        af = addr_family::ipv4;
        const struct sockaddr_in* p = (const struct sockaddr_in*)ifa_addr;
        std::memcpy(&addr, &(p->sin_addr), sizeof(struct in_addr));
        return;
    }
    if( ifa_addr->sa_family == AF_INET6 ) {
        af = addr_family::ipv6;
        const struct sockaddr_in6* p = (const struct sockaddr_in6*)ifa_addr;
        std::memcpy(&addr, &(p->sin6_addr), sizeof(struct in6_addr));
        return;
    }
    throw bad_address("Invalid address family");
}

bool ip_address::operator==(const ip_address& rhs) const {
    if( af != rhs.af ) return false;
    if( af == addr_family::none ) return true;
    if( is_v4() ) {
        return std::memcmp(v4addr(), rhs.v4addr(), sizeof(struct in_addr)) == 0;
    }
    return std::memcmp(v6addr(), rhs.v6addr(), sizeof(struct in6_addr)) == 0;
}

std::string ip_address::str() const {
    if( is_v4() ) {
        char dst[INET_ADDRSTRLEN];
        return std::string(inet_ntop(AF_INET, v4addr(), dst, INET_ADDRSTRLEN));
    }
    char dst[INET6_ADDRSTRLEN];
    return std::string(inet_ntop(AF_INET6, v6addr(), dst, INET6_ADDRSTRLEN));
}

bool has_ip_address(const ip_address& addr) {
    ifaddrs_wrapper ifw;
    return ifw.find(addr);
}

} // namespace cybozu
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: so_env.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-20 10:08:00 $
 *
 *  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 WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES 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): _______________________________________
 *
 *
 ************************************************************************/

#ifdef UNIX
#include <sys/types.h>
#include <strings.h>
#ifdef NP_LINUX
#include <stdarg.h>
#else
#include <sys/varargs.h>
#endif
// For vsnprintf()
#define NSP_vsnprintf vsnprintf
#endif // End UNIX

#ifdef WNT
#define _WINDOWS

#include <windows.h>
#include <direct.h>
#include <stdlib.h>
#include <shlobj.h>
#include <objidl.h>
// For vsnprintf()
#define NSP_vsnprintf _vsnprintf
#endif // End WNT

#include <sys/stat.h>
#include <errno.h>
#include "so_env.hxx"
#include "ns_debug.hxx"

// Tranform all strings like %20 in pPath to one char like space
/*int retoreUTF8(char* pPath)
{
    // Prepare buf
    int len = strlen(pPath) + 1;
    char* pBuf = (char*)malloc(len);
    memset(pBuf, 0, len);

    // Store the original pBuf and pPath
    char* pBufCur = pBuf;
    char* pPathCur = pPath;
    // ie, for %20, UTF8Numbers[0][0] = 2, UTF8Numbers[1][0] = 0
    char UTF8Numbers[2][2] = {{0, 0}, {0,0}};
    int temp;

    while (*pPathCur) {
        if (('%' == *pPathCur) && (0 != *(pPathCur + 1))
            && (0 != *(pPathCur + 2)))
        {
            UTF8Numbers[0][0] = *(pPathCur + 1);
            UTF8Numbers[1][0] = *(pPathCur + 2);
            temp = 0;
            temp = atoi(UTF8Numbers[0])*16 + atoi(UTF8Numbers[1]);
            *pBufCur = (char)temp;
            pBufCur++;
            pPathCur += 3;
        } else {
            *pBufCur++ = *pPathCur++;
        }
    }

    *pBufCur = 0;
    strcpy(pPath, pBuf);
    free(pBuf);
    return 0;
}*/

int
restoreUTF8(char *pPath)
{
    unsigned char *s, *d;

#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)

    s = d = (unsigned char *)pPath;
    do {
        if (*s == '%' && s[1] && s[2]) {
            *d++ = (XDIGIT (s[1]) << 4) + XDIGIT (s[2]);
            s += 2;
        } else
            *d++ = *s;
    } while (*s++);
    debug_fprintf(NSP_LOG_APPEND, "after restoreUTF8, pPath is %s\n", pPath);
    return 0;
}

// *aResult points the static string holding "/opt/staroffice8"
int findReadSversion(void** aResult, int bWnt, const char* tag, const char* entry)
{
#ifdef UNIX
    // The real space to hold "/opt/staroffice8"
    static char realFileName[NPP_PATH_MAX] = {0};
    memset(realFileName, 0, NPP_PATH_MAX);
    *aResult = realFileName;

    // Filename of lnk file, eg. "soffice"
    char lnkFileName[NPP_PATH_MAX] = {0};
    char* pTempZero = NULL;
    sprintf(lnkFileName, "%s/.mozilla/plugins/%s", getenv("HOME"), "libnpsoplugin.so");
    if ((0 > readlink(lnkFileName, realFileName, NPP_PATH_MAX)) ||
       (NULL == (pTempZero = strstr(realFileName, "/program/libnpsoplugin.so"))))
    {
        *realFileName = 0;
        return -1;
    }
    *pTempZero = 0;
    return 0;
#endif
#ifdef WNT
    static char realFileName[NPP_PATH_MAX] = {0};
    *aResult = realFileName;
    HKEY hKey;
    DWORD dwBufLen = NPP_PATH_MAX;
    LONG lRet;

    debug_fprintf(NSP_LOG_APPEND, "1 before before strstr realFileName is %s\n", realFileName);
    lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
       "SOFTWARE\\MozillaPlugins\\@sun.com/npsopluginmi;version=1.0",
       0, KEY_QUERY_VALUE, &hKey );
    debug_fprintf(NSP_LOG_APPEND, "2 before before strstr realFileName is %s\n", realFileName);
    if( lRet != ERROR_SUCCESS )
       return FALSE;

    lRet = RegQueryValueEx( hKey, "Path", NULL, NULL,
       (LPBYTE) realFileName, &dwBufLen);
    debug_fprintf(NSP_LOG_APPEND, "3 before before strstr realFileName is %s\n", realFileName);
    if( (lRet != ERROR_SUCCESS) || (dwBufLen > NPP_PATH_MAX) )
       return FALSE;

    RegCloseKey( hKey );
    char* pTempZero = NULL;
    debug_fprintf(NSP_LOG_APPEND, "before strstr realFileName is %s\n", realFileName);
    if (NULL == (pTempZero = strstr(realFileName, "\\program")))
    {
        *realFileName = 0;
        return -1;
    }
    *pTempZero = 0;
    debug_fprintf(NSP_LOG_APPEND, "realFileName is %s\n", realFileName);
    return 0;
#endif
}

// Return the install dir path of staroffice, return value like "/home/build/staroffice"
const char* findInstallDir()
{
    static char* pInstall = NULL;
    debug_fprintf(NSP_LOG_APPEND, "start of findInstallDir()\n");
    if (!pInstall)
    {
        findReadSversion((void**)&pInstall, 0, "["SECTION_NAME"]", SOFFICE_VERSION"=");
        if (!pInstall)
            pInstall = "";
    }
    return pInstall;
}

// Return the program dir path of staroffice, return value like "/home/build/staroffice/program"
const char* findProgramDir()
{
    static char sProgram[NPP_BUFFER_SIZE] = {0};
    if (!sProgram[0])
    {
        sprintf(sProgram, "%s/program", findInstallDir());
#ifdef WNT
        UnixToDosPath(sProgram);
#endif
    }
    return sProgram;
}

// Return the nsplugin executable file path, return value like "/home/build/staroffice/program/nsplugin"
const char* findNsExeFile()
{
    static char sNsExe[NPP_BUFFER_SIZE] = {0};

    if (!sNsExe[0])
    {
        sprintf(sNsExe, "%s/%s", findProgramDir(), PLUGIN_EXE_FILE_NAME);
#ifdef WNT
        UnixToDosPath(sNsExe);
#endif
     }
    return sNsExe;
}

// Return: "/home/build/staroffice/program" + original system library path
const char* getNewLibraryPath()
{
    static char pLPATH[NPP_PATH_MAX*4] = {0};

    if (!pLPATH[0])
    {
        const char* pProgram = findProgramDir();
        strcpy(pLPATH, "LD_LIBRARY_PATH=");
        strcat(pLPATH, pProgram);

        char* pLD = getenv("LD_LIBRARY_PATH");
        if (pLD)
        {
            strcat(pLPATH, ":");
            strcat(pLPATH, pLD);
        }
    }
    return pLPATH;
}

// Return SO executable absolute path, like "/home/build/staroffice/program/soffice"
const char* findSofficeExecutable()
{
    static char pSofficeExeccutable[NPP_PATH_MAX] = {0};
    if (!pSofficeExeccutable[0])
    {
        sprintf(pSofficeExeccutable, "%s/%s", findProgramDir(), STAROFFICE_EXE_FILE_NAME);
#ifdef WNT
        UnixToDosPath(pSofficeExeccutable);
#endif
    }

    return pSofficeExeccutable;
}

// Change Dos path such as c:\program\soffice to c:/program/soffice
int DosToUnixPath(char* sPath)
{
    if (!sPath)
        return -1;
    char* p = sPath;
    while (*p)
    {
        if(*p == '\\')
            *p = '/';
        p++;
    }
    return 0;

}

// Change Unix path such as program/soffice to program\soffice
int UnixToDosPath(char* sPath)
{
    if (!sPath)
        return -1;
    char* p = sPath;
    while (*p)
    {
        if(*p == '/')
            *p = '\\';
        p++;
    }
    return 0;

}

void NSP_WriteLog(int level,  const char* pFormat, ...)
{
#ifdef DEBUG
    va_list      ap;
    char         msgBuf[NPP_BUFFER_SIZE];
    static char  logName[NPP_PATH_MAX] = {0};
    FILE *       fp = NULL;
    int          dwPos,dwWriteBytes;

    va_start(ap,pFormat);
    NSP_vsnprintf(msgBuf, NPP_BUFFER_SIZE, pFormat, ap);
    va_end(ap);

    if (!logName[0])
    {
#ifdef UNIX
        const char* homeDir = getenv("HOME");
        sprintf(logName,"%s/%s",homeDir,"nsplugin.log");
#endif // End UNIX
#ifdef WNT
        char szPath[MAX_PATH];
        if (!SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, 0))
        {
             return;
        }
        char* homeDir = szPath;
        sprintf(logName,"%s\\%s", szPath, "nsplugin.log");
#endif // End WNT
    }
    else
        fp = fopen(logName, "a+");

    if (!fp)
        return;
    fputs(msgBuf, fp);
    fclose(fp);
#endif
}

<commit_msg>INTEGRATION: CWS nsplugin3 (1.2.32); FILE MERGED 2004/11/12 07:29:40 jmeng 1.2.32.5: change the display name from StarOffice to StarOffice/StarSuite 2004/11/12 03:22:45 jmeng 1.2.32.4: change Plugin to Plug-in 2004/11/12 02:05:36 jmeng 1.2.32.3: change product name from StarOffce to StarOffice/StarSuite 2004/10/12 03:40:58 rchen 1.2.32.2: for compile in windows 2004/10/12 03:10:22 jmeng 1.2.32.1: add dynamic OpenOffice.org / StarOffice support<commit_after>/*************************************************************************
 *
 *  $RCSfile: so_env.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2004-11-26 16:01:41 $
 *
 *  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 WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES 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): _______________________________________
 *
 *
 ************************************************************************/

#ifdef UNIX
#include <sys/types.h>
#include <strings.h>
#ifdef NP_LINUX
#include <stdarg.h>
#else
#include <sys/varargs.h>
#endif
// For vsnprintf()
#define NSP_vsnprintf vsnprintf
#include "nsp_func.hxx"
#endif // End UNIX

#ifdef WNT
#define _WINDOWS

#include <windows.h>
#include <direct.h>
#include <stdlib.h>
#include <shlobj.h>
#include <objidl.h>
// For vsnprintf()
#define NSP_vsnprintf _vsnprintf
#endif // End WNT

#include <sys/stat.h>
#include <errno.h>
#include "so_env.hxx"
#include "ns_debug.hxx"

#define PLUGIN_NAME         "OpenOffice.org"

// Tranform all strings like %20 in pPath to one char like space
/*int retoreUTF8(char* pPath)
{
    // Prepare buf
    int len = strlen(pPath) + 1;
    char* pBuf = (char*)malloc(len);
    memset(pBuf, 0, len);

    // Store the original pBuf and pPath
    char* pBufCur = pBuf;
    char* pPathCur = pPath;
    // ie, for %20, UTF8Numbers[0][0] = 2, UTF8Numbers[1][0] = 0
    char UTF8Numbers[2][2] = {{0, 0}, {0,0}};
    int temp;

    while (*pPathCur) {
        if (('%' == *pPathCur) && (0 != *(pPathCur + 1))
            && (0 != *(pPathCur + 2)))
        {
            UTF8Numbers[0][0] = *(pPathCur + 1);
            UTF8Numbers[1][0] = *(pPathCur + 2);
            temp = 0;
            temp = atoi(UTF8Numbers[0])*16 + atoi(UTF8Numbers[1]);
            *pBufCur = (char)temp;
            pBufCur++;
            pPathCur += 3;
        } else {
            *pBufCur++ = *pPathCur++;
        }
    }

    *pBufCur = 0;
    strcpy(pPath, pBuf);
    free(pBuf);
    return 0;
}*/

int
restoreUTF8(char *pPath)
{
    unsigned char *s, *d;

#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)

    s = d = (unsigned char *)pPath;
    do {
        if (*s == '%' && s[1] && s[2]) {
            *d++ = (XDIGIT (s[1]) << 4) + XDIGIT (s[2]);
            s += 2;
        } else
            *d++ = *s;
    } while (*s++);
    debug_fprintf(NSP_LOG_APPEND, "after restoreUTF8, pPath is %s\n", pPath);
    return 0;
}

// *aResult points the static string holding "/opt/staroffice8"
int findReadSversion(void** aResult, int bWnt, const char* tag, const char* entry)
{
#ifdef UNIX
    // The real space to hold "/opt/staroffice8"
    static char realFileName[NPP_PATH_MAX] = {0};
    memset(realFileName, 0, NPP_PATH_MAX);
    *aResult = realFileName;

    // Filename of lnk file, eg. "soffice"
    char lnkFileName[NPP_PATH_MAX] = {0};
    char* pTempZero = NULL;
    sprintf(lnkFileName, "%s/.mozilla/plugins/%s", getenv("HOME"), "libnpsoplugin.so");
    if ((0 > readlink(lnkFileName, realFileName, NPP_PATH_MAX)) ||
       (NULL == (pTempZero = strstr(realFileName, "/program/libnpsoplugin.so"))))
    {
        *realFileName = 0;
        return -1;
    }
    *pTempZero = 0;
    return 0;
#endif
#ifdef WNT
    static char realFileName[NPP_PATH_MAX] = {0};
    *aResult = realFileName;
    HKEY hKey;
    DWORD dwBufLen = NPP_PATH_MAX;
    LONG lRet;

    debug_fprintf(NSP_LOG_APPEND, "1 before before strstr realFileName is %s\n", realFileName);
    lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
       "SOFTWARE\\MozillaPlugins\\@sun.com/npsopluginmi;version=1.0",
       0, KEY_QUERY_VALUE, &hKey );
    debug_fprintf(NSP_LOG_APPEND, "2 before before strstr realFileName is %s\n", realFileName);
    if( lRet != ERROR_SUCCESS )
       return FALSE;

    lRet = RegQueryValueEx( hKey, "Path", NULL, NULL,
       (LPBYTE) realFileName, &dwBufLen);
    debug_fprintf(NSP_LOG_APPEND, "3 before before strstr realFileName is %s\n", realFileName);
    if( (lRet != ERROR_SUCCESS) || (dwBufLen > NPP_PATH_MAX) )
       return FALSE;

    RegCloseKey( hKey );
    char* pTempZero = NULL;
    debug_fprintf(NSP_LOG_APPEND, "before strstr realFileName is %s\n", realFileName);
    if (NULL == (pTempZero = strstr(realFileName, "\\program")))
    {
        *realFileName = 0;
        return -1;
    }
    *pTempZero = 0;
    debug_fprintf(NSP_LOG_APPEND, "realFileName is %s\n", realFileName);
    return 0;
#endif
}

// Return the install dir path of staroffice, return value like "/home/build/staroffice"
const char* findInstallDir()
{
    static char* pInstall = NULL;
    debug_fprintf(NSP_LOG_APPEND, "start of findInstallDir()\n");
    if (!pInstall)
    {
        findReadSversion((void**)&pInstall, 0, "["SECTION_NAME"]", SOFFICE_VERSION"=");
        if (!pInstall)
            pInstall = "";
    }
    return pInstall;
}

// Return the program dir path of staroffice, return value like "/home/build/staroffice/program"
const char* findProgramDir()
{
    static char sProgram[NPP_BUFFER_SIZE] = {0};
    if (!sProgram[0])
    {
        sprintf(sProgram, "%s/program", findInstallDir());
#ifdef WNT
        UnixToDosPath(sProgram);
#endif
    }
    return sProgram;
}

// Return the nsplugin executable file path, return value like "/home/build/staroffice/program/nsplugin"
const char* findNsExeFile()
{
    static char sNsExe[NPP_BUFFER_SIZE] = {0};

    if (!sNsExe[0])
    {
        sprintf(sNsExe, "%s/%s", findProgramDir(), PLUGIN_EXE_FILE_NAME);
#ifdef WNT
        UnixToDosPath(sNsExe);
#endif
     }
    return sNsExe;
}

// Return: "/home/build/staroffice/program" + original system library path
const char* getNewLibraryPath()
{
    static char pLPATH[NPP_PATH_MAX*4] = {0};

    if (!pLPATH[0])
    {
        const char* pProgram = findProgramDir();
        strcpy(pLPATH, "LD_LIBRARY_PATH=");
        strcat(pLPATH, pProgram);

        char* pLD = getenv("LD_LIBRARY_PATH");
        if (pLD)
        {
            strcat(pLPATH, ":");
            strcat(pLPATH, pLD);
        }
    }
    return pLPATH;
}

// Return SO executable absolute path, like "/home/build/staroffice/program/soffice"
const char* findSofficeExecutable()
{
    static char pSofficeExeccutable[NPP_PATH_MAX] = {0};
    if (!pSofficeExeccutable[0])
    {
        sprintf(pSofficeExeccutable, "%s/%s", findProgramDir(), STAROFFICE_EXE_FILE_NAME);
#ifdef WNT
        UnixToDosPath(pSofficeExeccutable);
#endif
    }

    return pSofficeExeccutable;
}

// Change Dos path such as c:\program\soffice to c:/program/soffice
int DosToUnixPath(char* sPath)
{
    if (!sPath)
        return -1;
    char* p = sPath;
    while (*p)
    {
        if(*p == '\\')
            *p = '/';
        p++;
    }
    return 0;

}

// Change Unix path such as program/soffice to program\soffice
int UnixToDosPath(char* sPath)
{
    if (!sPath)
        return -1;
    char* p = sPath;
    while (*p)
    {
        if(*p == '/')
            *p = '\\';
        p++;
    }
    return 0;

}

#ifdef UNIX
char productName[128] = {0};
char* NSP_getProductName()
{
    if(productName[0])
        return productName;
    char fullBootstrapIniPath[1024] = {0};
    const char* pFullFilePath = findProgramDir();
    if(0 == *pFullFilePath)
    {
        strcpy(productName, PLUGIN_NAME);
        return productName;
    }
    sprintf(fullBootstrapIniPath, "%s/%s", pFullFilePath,
        "bootstraprc");

    FILE* fp = fopen(fullBootstrapIniPath, "r");

    if (NULL == fp)
    {
        strcpy(productName, PLUGIN_NAME);
        return productName;
    }
    char line[4096] = {0};
    char *pStart = 0;
    char *pEnd = 0;
    while(!feof(fp))
    {
        fgets( line, sizeof(line), fp );
        if (NULL == (pStart = strstr( line, "ProductKey=" )))
            continue;
        pStart += strlen("ProductKey=");
        if (NULL == (pEnd = strchr( pStart, ' ' )) &&
           (NULL == (pEnd = strchr( pStart, '\r' ))))
            continue;
        *pEnd = 0;
        strcpy(productName, pStart);
    }
    fclose(fp);
    if ((*productName == 0) ||
        (0 != STRNICMP(productName, "StarOffice", sizeof("StarOffice"))))
    {
        strcpy(productName, PLUGIN_NAME);
        return productName;
    }
    memset(productName, 0, sizeof(productName));
    strcat(productName, "StarOffice/StarSuite");
    return productName;
}

char PluginName[1024] = {0};
char* NSP_getPluginName()
{
    if(*PluginName)
        return PluginName;
    sprintf(PluginName, "%s Plug-in", NSP_getProductName());
    return PluginName;
}

char PluginDesc[1024] = {0};
char* NSP_getPluginDesc()
{
    if(*PluginDesc)
        return PluginDesc;

    sprintf(PluginDesc, "%s Plug-in handles all its documents",
        productName);
    return PluginDesc;
}
#endif //end of UNIX

void NSP_WriteLog(int level,  const char* pFormat, ...)
{
#ifdef DEBUG
    va_list      ap;
    char         msgBuf[NPP_BUFFER_SIZE];
    static char  logName[NPP_PATH_MAX] = {0};
    FILE *       fp = NULL;
    int          dwPos,dwWriteBytes;

    va_start(ap,pFormat);
    NSP_vsnprintf(msgBuf, NPP_BUFFER_SIZE, pFormat, ap);
    va_end(ap);

    if (!logName[0])
    {
#ifdef UNIX
        const char* homeDir = getenv("HOME");
        sprintf(logName,"%s/%s",homeDir,"nsplugin.log");
#endif // End UNIX
#ifdef WNT
        char szPath[MAX_PATH];
        if (!SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, 0))
        {
             return;
        }
        char* homeDir = szPath;
        sprintf(logName,"%s\\%s", szPath, "nsplugin.log");
#endif // End WNT
    }
    else
        fp = fopen(logName, "a+");

    if (!fp)
        return;
    fputs(msgBuf, fp);
    fclose(fp);
#endif
}

<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include "expander.hpp"

using namespace std;

namespace bohrium {
namespace filter {
namespace composite {

int Expander::expand_matmul(bh_ir& bhir, int idx)
{
    return 0;
}

}}}
<commit_msg>composite_expansion: Implemented matmul expansion.<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include "expander.hpp"

using namespace std;

namespace bohrium {
namespace filter {
namespace composite {

int Expander::expand_matmul(bh_ir& bhir, int pc)
{
    int start_pc = pc;
    bh_instruction& composite = bhir.instr_list[pc];
    composite.opcode = BH_NONE;                     // Lazy choice... no re-use just NOP it.

    bh_view out = composite.operand[0];             // Grab operands
    bh_view a = composite.operand[1];
    bh_view b = composite.operand[2];

    int n = a.shape[0];                             // Grab the shape
    int m = a.shape[1];
    int k = b.shape[0];
                                                    // Construct intermediary operands
    bh_view a_3d = a;                               // Needs broadcast
    bh_view b_3d = b;                               // Needs transposition + broadcast

    a_3d.ndim = 3;
    b_3d.ndim = 3;
    a_3d.shape[0] = b_3d.shape[0] = n;               // Set the shape
    a_3d.shape[1] = b_3d.shape[1] = k;
    a_3d.shape[2] = b_3d.shape[2] = m;

    a_3d.stride[0] = a.stride[0];                   // Construct broadcast
    a_3d.stride[1] = 0;
    a_3d.stride[2] = a.stride[1];

    b_3d.stride[0] = 0;                             // Construct transpose + broadcast
    b_3d.stride[1] = b.stride[1];
    b_3d.stride[2] = b.stride[0];

    bh_view c_3d = b_3d;                            // Construct temp for mul-result
    bh_intp nelements = 1;                          // Count number of elements
    for(bh_intp dim=c_3d.ndim-1; dim >= 0; --dim) { // Set contiguous stride
        c_3d.stride[dim] = nelements;
        nelements *= c_3d.shape[dim];
    }
    c_3d.start = 0;
    c_3d.base = make_base(b_3d.base->type, nelements);

                                                    // Expand sequence
    inject(bhir, ++pc, BH_MULTIPLY, c_3d, a_3d, b_3d);
    bh_instruction reduce;
    reduce.opcode = BH_ADD_REDUCE;
    reduce.operand[0] = out;
    reduce.operand[1] = c_3d;
    bh_flag_constant(&reduce.operand[2]);
    reduce.constant.type = BH_INT64;
    reduce.constant.value.int64 = (int64_t)1;

    bhir.instr_list.insert(bhir.instr_list.begin()+(++pc), reduce);
    inject(bhir, ++pc, BH_FREE, c_3d);
    inject(bhir, ++pc, BH_DISCARD, c_3d);
    //inject(bhir, ++pc, BH_ADD_REDUCE, out, c_3d, -1);

    return pc-start_pc;
}

}}}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbChangeInformationImageFilter.h"
#include "otbImageFileReader.h"
#include "otbImage.h"

int otbChangeInformationImageFilter(int itkNotUsed(argc), char* argv[])
{
  const char* inputFilename(argv[1]);

  typedef otb::Image<float, 2> ImageType;
  typedef otb::ChangeInformationImageFilter<ImageType> FilterType;
  typedef otb::ImageFileReader<ImageType>              ReaderType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFilename);

  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());
  // try to set a different ProjRef
  std::string newProj("Fake ProjRef");
  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey, &newProj);
  // erase that choice
  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey, nullptr);
  // add a no data to the image
  std::vector<bool> flags;
  flags.push_back(true);
  std::vector<double> nodata;
  nodata.push_back(0.0);
  filter->SetOutputMetaData<std::vector<bool>>(otb::MetaDataKey::NoDataValueAvailable, &flags);
  filter->SetOutputMetaData<std::vector<double>>(otb::MetaDataKey::NoDataValue, &nodata);
  filter->UpdateOutputInformation();

  ImageType::Pointer outImage = filter->GetOutput();
  if (!outImage->GetProjectionRef().empty())
  {
    std::cout << "Projection is supposed to be removed but is still present !" << std::endl;
    return EXIT_FAILURE;
  }

  itk::MetaDataDictionary& dict = outImage->GetMetaDataDictionary();
  if (!dict.HasKey(otb::MetaDataKey::NoDataValueAvailable) || !dict.HasKey(otb::MetaDataKey::NoDataValue))
  {
    std::cout << "Missing no data metadata !" << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<commit_msg>REFAC: don't use GetProjectionRef in ChangeInformationImageFilter because the method don't use the itk metadata dictionary anymore<commit_after>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbChangeInformationImageFilter.h"
#include "otbImageFileReader.h"
#include "otbImage.h"

int otbChangeInformationImageFilter(int itkNotUsed(argc), char* argv[])
{
  const char* inputFilename(argv[1]);

  typedef otb::Image<float, 2> ImageType;
  typedef otb::ChangeInformationImageFilter<ImageType> FilterType;
  typedef otb::ImageFileReader<ImageType>              ReaderType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFilename);

  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());
  // try to set a different ProjRef
  std::string newProj("Fake ProjRef");
  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey, &newProj);
  // erase that choice
  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey, nullptr);
  // add a no data to the image
  std::vector<bool> flags;
  flags.push_back(true);
  std::vector<double> nodata;
  nodata.push_back(0.0);
  filter->SetOutputMetaData<std::vector<bool>>(otb::MetaDataKey::NoDataValueAvailable, &flags);
  filter->SetOutputMetaData<std::vector<double>>(otb::MetaDataKey::NoDataValue, &nodata);
  filter->UpdateOutputInformation();

  ImageType::Pointer outImage = filter->GetOutput();

  // TODO: RemoveOssim. ChangeInformationImageFilter should change the ImageMetadata object stored in
  // the image instead of modifying the itk metadata dictionary. GetProjectionRef() look for the
  // projection in ImageMetadata now, so we can't use this method in the test. The temporary solution
  // is to look in the itk dictionary instead (this was the old behavior of GetProjectionRef). But
  // when ChangeInformationImageFilter will be refactored, GetProjectionRef should be used again..

  //if (!outImage->GetProjectionRef().empty())
  if (outImage->GetMetaDataDictionary().HasKey(otb::MetaDataKey::ProjectionRefKey))
  {
    std::cout << "Projection is supposed to be removed but is still present !" << std::endl;
    return EXIT_FAILURE;
  }

  itk::MetaDataDictionary& dict = outImage->GetMetaDataDictionary();

  if (!dict.HasKey(otb::MetaDataKey::NoDataValueAvailable) || !dict.HasKey(otb::MetaDataKey::NoDataValue))
  {
    std::cout << "Missing no data metadata !" << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 emo-framework project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of the project nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER 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 "native_app_glue.h"

#include "emo/Runtime.h"
#include "emo/Engine.h"

emo::Engine* engine;

void android_main(struct android_app* state) {

    app_dummy();

    engine = new emo::Engine();

    state->userData = engine;
    state->onAppCmd = app_handle_cmd;
    state->onInputEvent = app_handle_input;
    engine->app = state;

    engine->onInitEngine();

    while (1) {
        int ident;
        int events;
        struct android_poll_source* source;

        while ((ident=ALooper_pollAll(engine->animating ? 0 : -1, NULL, &events,
                (void**)&source)) >= 0) {

            // Process this event.
            if (source != NULL) {
                source->process(state, source);
            }

            // Process the user queue.
            if (ident == LOOPER_ID_USER) {
                if (engine->getSensorEventQueue() != NULL) {
                    ASensorEvent event;
                    while (ASensorEventQueue_getEvents(
                            engine->getSensorEventQueue(), &event, 1) > 0) {
                        engine->onSensorEvent(&event);
                    }
                }
            }

            if (state->destroyRequested != 0) {
                engine->onDispose();
                delete engine;
                return;
            }
        }

        if (engine->animating) {
            engine->onDrawFrame();
        }
    }
}
<commit_msg>add builtin_expect to main loop<commit_after>// Copyright (c) 2011 emo-framework project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of the project nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER 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 "native_app_glue.h"

#include "emo/Runtime.h"
#include "emo/Engine.h"

emo::Engine* engine;

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

void android_main(struct android_app* state) {

    app_dummy();

    engine = new emo::Engine();

    state->userData = engine;
    state->onAppCmd = app_handle_cmd;
    state->onInputEvent = app_handle_input;
    engine->app = state;

    engine->onInitEngine();

    while (1) {
        int ident;
        int events;
        struct android_poll_source* source;

        while ((ident=ALooper_pollAll(engine->animating ? 0 : -1, NULL, &events,
                (void**)&source)) >= 0) {

            // Process this event.
            if (source != NULL) {
                source->process(state, source);
            }

            // Process the user queue.
            if (ident == LOOPER_ID_USER) {
                if (engine->getSensorEventQueue() != NULL) {
                    ASensorEvent event;
                    while (ASensorEventQueue_getEvents(
                            engine->getSensorEventQueue(), &event, 1) > 0) {
                        engine->onSensorEvent(&event);
                    }
                }
            }

            if (unlikely(state->destroyRequested != 0)) {
                engine->onDispose();
                delete engine;
                return;
            }
        }

        if (likely(engine->animating)) {
            engine->onDrawFrame();
        }
    }
}
<|endoftext|>


<commit_before>/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>

#include <iostream>
#include <sstream>

#include <curl/curl.h>
#include <curl/types.h>

class EasyCurl
{
    public:

        struct StreamPair
        {
            StreamPair(std::ostream* stream1, std::ostream* stream2=0):
                _stream1(stream1),
                _stream2(stream2) {}

            std::ostream* _stream1;
            std::ostream* _stream2;
        };

        static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
        {
            size_t realsize = size * nmemb;
            StreamPair* sp = (StreamPair*)data;

            if (sp->_stream1) sp->_stream1->write((const char*)ptr, realsize);
            if (sp->_stream2) sp->_stream2->write((const char*)ptr, realsize);

            return realsize;
        }

        EasyCurl()
        {
            _curl = curl_easy_init();

            curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
            curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
        }

        ~EasyCurl()
        {
            if (_curl) curl_easy_cleanup(_curl);

            _curl = 0;
        }

        osgDB::ReaderWriter::ReadResult read(const std::string& proxyAddress, const std::string& fileName, StreamPair& sp)
        {
            if(!proxyAddress.empty())
            {
                osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
                curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
            }

            curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&sp);

            CURLcode res = curl_easy_perform(_curl);

            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);

            if (res==0)
            {
                long code;
                if(!proxyAddress.empty())
                {
                    curl_easy_getinfo(_curl, CURLINFO_HTTP_CONNECTCODE, &code);
                }
                else
                {
                    curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
                }

                if (code>=400)
                {
                    osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<", error code = "<<code<<std::endl;
                    return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
                }

                return osgDB::ReaderWriter::ReadResult::FILE_LOADED;

            }
            else
            {
                osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" error = "<<curl_easy_strerror(res)<<std::endl;
                return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
            }
        }

    protected:

        CURL* _curl;
};

class ReaderWriterCURL : public osgDB::ReaderWriter
{
    public:

        ReaderWriterCURL()
        {
        }

        ~ReaderWriterCURL()
        {
        }

        virtual const char* className() const { return "HTTP Protocol Model Reader"; }

        virtual bool acceptsExtension(const std::string& extension) const
        {
            return osgDB::equalCaseInsensitive(extension,"curl");
        }

        enum ObjectType
        {
            OBJECT,
            ARCHIVE,
            IMAGE,
            HEIGHTFIELD,
            NODE
        };

        virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
        {
            if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
            else return readFile(ARCHIVE,fileName,options);
        }

        virtual ReadResult readObject(const std::string& fileName, const Options* options) const
        {
            return readFile(OBJECT,fileName,options);
        }

        virtual ReadResult readImage(const std::string& fileName, const Options *options) const
        {
            return readFile(IMAGE,fileName,options);
        }

        virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
        {
            return readFile(HEIGHTFIELD,fileName,options);
        }

        virtual ReadResult readNode(const std::string& fileName, const Options *options) const
        {
            return readFile(NODE,fileName,options);
        }

        ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
        {
            switch(objectType)
            {
            case(OBJECT): return rw->readObject(fin,options);
            case(ARCHIVE): return rw->openArchive(fin,options);
            case(IMAGE): return rw->readImage(fin,options);
            case(HEIGHTFIELD): return rw->readHeightField(fin,options);
            case(NODE): return rw->readNode(fin,options);
            default: break;
            }
            return ReadResult::FILE_NOT_HANDLED;
        }

        virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const
        {
            std::string cacheFilePath, cacheFileName;
            std::string proxyAddress, optProxy, optProxyPort;

            if (options)
            {
                std::istringstream iss(options->getOptionString());
                std::string opt;
                while (iss >> opt)
                {
                    int index = opt.find( "=" );
                    if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
                        cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
                        optProxy = opt.substr( index+1 );
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
                        optProxyPort = opt.substr( index+1 );
                }

                //Setting Proxy by OSG Options
                if(!optProxy.empty())
                    if(!optProxyPort.empty())
                        proxyAddress = optProxy + ":" + optProxyPort;
                    else
                        proxyAddress = optProxy + ":8080"; //Port not found, using default
            }

            if (!osgDB::containsServerAddress(fullFileName))
            {
                if (options && !(options->getDatabasePathList().empty()))
                {
                    if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
                    {
                        std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;

                        return readFile(objectType, newFileName,options);
                    }
                }

                return ReadResult::FILE_NOT_HANDLED;
            }

            std::string fileName;
            std::string ext = osgDB::getFileExtension(fullFileName);
            if (ext=="curl")
            {
                fileName = osgDB::getNameLessExtension(fullFileName);
            }
            else
            {
                fileName = fullFileName;
            }

            //Getting CURL Environment Variables (If found rewrite OSG Options)
            const char* fileCachePath = getenv("OSG_FILE_CACHE");
            if (fileCachePath) //Env Cache Directory
                cacheFilePath = std::string(fileCachePath);

            if (!cacheFilePath.empty())
            {
                cacheFileName = cacheFilePath + "/" +
                                osgDB::getServerAddress(fileName) + "/" +
                                osgDB::getServerFileName(fileName);
            }

            if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
            {
                osg::notify(osg::INFO) << "Reading cache file " << cacheFileName << std::endl;
                ReadResult result = osgDB::Registry::instance()->readObject(cacheFileName,options);
                return result;
            }

            osgDB::ReaderWriter *reader =
                osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));

            if (!reader)
            {
                osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
            if (proxyEnvAddress) //Env Proxy Settings
            {
                const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env

                if(proxyEnvPort)
                    proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
                else
                    proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
            }

            std::stringstream buffer;

            EasyCurl::StreamPair sp(&buffer);

            ReadResult result = _easyCurl.read(proxyAddress, fileName, sp);

            if (result.status()==ReadResult::FILE_LOADED)
            {
                osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
                if (!local_opt) local_opt = new Options;

                local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));

                ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );

                local_opt->getDatabasePathList().pop_front();

                if (!cacheFilePath.empty() && readResult.validObject())
                {
                    osg::notify(osg::NOTICE)<<"Writing cache file "<<cacheFileName<<std::endl;

                    std::string filePath = osgDB::getFilePath(cacheFileName);
                    if (osgDB::fileExists(filePath) || osgDB::makeDirectory(filePath))
                    {
                        switch(objectType)
                        {
                        case(OBJECT): osgDB::writeObjectFile( *(readResult.getObject()), cacheFileName ); break;
                        case(IMAGE): osgDB::writeImageFile( *(readResult.getImage()), cacheFileName ); break;
                        case(HEIGHTFIELD): osgDB::writeHeightFieldFile( *(readResult.getHeightField()), cacheFileName ); break;
                        case(NODE): osgDB::writeNodeFile( *(readResult.getNode()), cacheFileName ); break;
                        default: break;
                        }
                    }
                    else
                    {
                        osg::notify(osg::NOTICE)<<"Error: Failed to created directory "<<filePath<<std::endl;
                    }

                }

                return readResult;
            }
            else
            {
                return result;
            }
        }

    protected:

        mutable EasyCurl _easyCurl;
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterCURL)
<commit_msg>Introduced a thread safe map which manages a single EasyCurl object per thread.<commit_after>/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>

#include <iostream>
#include <sstream>

#include <curl/curl.h>
#include <curl/types.h>

class EasyCurl : public osg::Referenced
{
    public:

        struct StreamPair
        {
            StreamPair(std::ostream* stream1, std::ostream* stream2=0):
                _stream1(stream1),
                _stream2(stream2) {}

            std::ostream* _stream1;
            std::ostream* _stream2;
        };

        static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
        {
            size_t realsize = size * nmemb;
            StreamPair* sp = (StreamPair*)data;

            if (sp->_stream1) sp->_stream1->write((const char*)ptr, realsize);
            if (sp->_stream2) sp->_stream2->write((const char*)ptr, realsize);

            return realsize;
        }

        EasyCurl()
        {
            osg::notify(osg::INFO)<<"EasyCurl::EasyCurl()"<<std::endl;

            _curl = curl_easy_init();

            curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
            curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
        }

        ~EasyCurl()
        {
            osg::notify(osg::INFO)<<"EasyCurl::~EasyCurl()"<<std::endl;

            if (_curl) curl_easy_cleanup(_curl);

            _curl = 0;
        }

        osgDB::ReaderWriter::ReadResult read(const std::string& proxyAddress, const std::string& fileName, StreamPair& sp)
        {
            if(!proxyAddress.empty())
            {
                osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
                curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
            }

            curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&sp);

            CURLcode res = curl_easy_perform(_curl);

            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);

            if (res==0)
            {
                long code;
                if(!proxyAddress.empty())
                {
                    curl_easy_getinfo(_curl, CURLINFO_HTTP_CONNECTCODE, &code);
                }
                else
                {
                    curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
                }

                if (code>=400)
                {
                    osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<", error code = "<<code<<std::endl;
                    return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
                }

                return osgDB::ReaderWriter::ReadResult::FILE_LOADED;

            }
            else
            {
                osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" error = "<<curl_easy_strerror(res)<<std::endl;
                return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
            }
        }

    protected:

        // disallow copying
        EasyCurl(const EasyCurl& rhs):_curl(rhs._curl) {}
        EasyCurl& operator = (const EasyCurl&) { return *this; }

        CURL* _curl;
};

class ReaderWriterCURL : public osgDB::ReaderWriter
{
    public:

        ReaderWriterCURL()
        {
        }

        ~ReaderWriterCURL()
        {
        }

        virtual const char* className() const { return "HTTP Protocol Model Reader"; }

        virtual bool acceptsExtension(const std::string& extension) const
        {
            return osgDB::equalCaseInsensitive(extension,"curl");
        }

        enum ObjectType
        {
            OBJECT,
            ARCHIVE,
            IMAGE,
            HEIGHTFIELD,
            NODE
        };

        virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
        {
            if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
            else return readFile(ARCHIVE,fileName,options);
        }

        virtual ReadResult readObject(const std::string& fileName, const Options* options) const
        {
            return readFile(OBJECT,fileName,options);
        }

        virtual ReadResult readImage(const std::string& fileName, const Options *options) const
        {
            return readFile(IMAGE,fileName,options);
        }

        virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
        {
            return readFile(HEIGHTFIELD,fileName,options);
        }

        virtual ReadResult readNode(const std::string& fileName, const Options *options) const
        {
            return readFile(NODE,fileName,options);
        }

        ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
        {
            switch(objectType)
            {
            case(OBJECT): return rw->readObject(fin,options);
            case(ARCHIVE): return rw->openArchive(fin,options);
            case(IMAGE): return rw->readImage(fin,options);
            case(HEIGHTFIELD): return rw->readHeightField(fin,options);
            case(NODE): return rw->readNode(fin,options);
            default: break;
            }
            return ReadResult::FILE_NOT_HANDLED;
        }

        virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const
        {
            std::string cacheFilePath, cacheFileName;
            std::string proxyAddress, optProxy, optProxyPort;

            if (options)
            {
                std::istringstream iss(options->getOptionString());
                std::string opt;
                while (iss >> opt)
                {
                    int index = opt.find( "=" );
                    if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
                        cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
                        optProxy = opt.substr( index+1 );
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
                        optProxyPort = opt.substr( index+1 );
                }

                //Setting Proxy by OSG Options
                if(!optProxy.empty())
                    if(!optProxyPort.empty())
                        proxyAddress = optProxy + ":" + optProxyPort;
                    else
                        proxyAddress = optProxy + ":8080"; //Port not found, using default
            }

            if (!osgDB::containsServerAddress(fullFileName))
            {
                if (options && !(options->getDatabasePathList().empty()))
                {
                    if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
                    {
                        std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;

                        return readFile(objectType, newFileName,options);
                    }
                }

                return ReadResult::FILE_NOT_HANDLED;
            }

            std::string fileName;
            std::string ext = osgDB::getFileExtension(fullFileName);
            if (ext=="curl")
            {
                fileName = osgDB::getNameLessExtension(fullFileName);
            }
            else
            {
                fileName = fullFileName;
            }

            //Getting CURL Environment Variables (If found rewrite OSG Options)
            const char* fileCachePath = getenv("OSG_FILE_CACHE");
            if (fileCachePath) //Env Cache Directory
                cacheFilePath = std::string(fileCachePath);

            if (!cacheFilePath.empty())
            {
                cacheFileName = cacheFilePath + "/" +
                                osgDB::getServerAddress(fileName) + "/" +
                                osgDB::getServerFileName(fileName);
            }

            if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
            {
                osg::notify(osg::INFO) << "Reading cache file " << cacheFileName << std::endl;
                ReadResult result = osgDB::Registry::instance()->readObject(cacheFileName,options);
                return result;
            }

            osgDB::ReaderWriter *reader =
                osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));

            if (!reader)
            {
                osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
            if (proxyEnvAddress) //Env Proxy Settings
            {
                const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env

                if(proxyEnvPort)
                    proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
                else
                    proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
            }

            std::stringstream buffer;

            EasyCurl::StreamPair sp(&buffer);

            //ReadResult result = _easyCurl.read(proxyAddress, fileName, sp);
            ReadResult result = getEasyCurl().read(proxyAddress, fileName, sp);

            if (result.status()==ReadResult::FILE_LOADED)
            {
                osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
                if (!local_opt) local_opt = new Options;

                local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));

                ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );

                local_opt->getDatabasePathList().pop_front();

                if (!cacheFilePath.empty() && readResult.validObject())
                {
                    osg::notify(osg::INFO)<<"Writing cache file "<<cacheFileName<<std::endl;

                    std::string filePath = osgDB::getFilePath(cacheFileName);
                    if (osgDB::fileExists(filePath) || osgDB::makeDirectory(filePath))
                    {
                        switch(objectType)
                        {
                        case(OBJECT): osgDB::writeObjectFile( *(readResult.getObject()), cacheFileName ); break;
                        case(IMAGE): osgDB::writeImageFile( *(readResult.getImage()), cacheFileName ); break;
                        case(HEIGHTFIELD): osgDB::writeHeightFieldFile( *(readResult.getHeightField()), cacheFileName ); break;
                        case(NODE): osgDB::writeNodeFile( *(readResult.getNode()), cacheFileName ); break;
                        default: break;
                        }
                    }
                    else
                    {
                        osg::notify(osg::NOTICE)<<"Error: Failed to created directory "<<filePath<<std::endl;
                    }

                }

                return readResult;
            }
            else
            {
                return result;
            }
        }

    protected:

        typedef std::map<OpenThreads::Thread*, osg::ref_ptr<EasyCurl> > ThreadCurlMap;

        EasyCurl& getEasyCurl() const
        {
            OpenThreads::ScopedLock<OpenThreads::Mutex>  lock(_threadCurlMapMutex);

            osg::ref_ptr<EasyCurl>& ec = _threadCurlMap[OpenThreads::Thread::CurrentThread()];
            if (!ec) ec = new EasyCurl;

            return *ec;
        }

        mutable OpenThreads::Mutex  _threadCurlMapMutex;
        mutable ThreadCurlMap       _threadCurlMap;
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterCURL)
<|endoftext|>