<commit_before>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_GENERICOBJECT_HXX_
#define _QITYPE_DETAILS_GENERICOBJECT_HXX_

#include <qi/future.hpp>
#include <qitype/typeobject.hpp>
#include <qitype/details/typeimpl.hxx>

namespace qi {

  namespace detail
  {

    template <typename T>
    inline void futureAdapter(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<T> promise)
    {

      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }

      GenericValuePtr val =  metaFut.value();
      Type* targetType = typeOf<T>();
      try
      {
        std::pair<GenericValuePtr, bool> conv = val.convert(targetType);
        if (!conv.first.type)
          promise.setError(std::string("Unable to convert call result to target type:")
            + val.type->infoString() + " -> " + targetType->infoString());
        else
        {
          T* res = (T*)conv.first.type->ptrFromStorage(&conv.first.value);
          promise.setValue(*res);
        }
        if (conv.second)
          conv.first.destroy();
      }
      catch(const std::exception& e)
      {
        promise.setError(std::string("Return argument conversion error: ") + e.what());
      }
      val.destroy();
    }

    template <typename T>
    inline void futureAdapterVal(qi::Future<qi::GenericValue> metaFut, qi::Promise<T> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      const GenericValue& val =  metaFut.value();
      try
      {
        promise.setValue(val.to<T>());
      }
      catch (const std::exception& e)
      {
        promise.setError(std::string("Return argument conversion error: ") + e.what());
      }
    }

    template<>
    inline void futureAdapterVal(qi::Future<qi::GenericValue> metaFut, qi::Promise<GenericValue> promise)
    {
      if (metaFut.hasError())
        promise.setError(metaFut.error());
      else
        promise.setValue(metaFut.value());
    }

    template <>
    inline void futureAdapter<void>(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<void> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      promise.setValue(0);
    }

  }

  /* Generate qi::FutureSync<R> GenericObject::call(methodname, args...)
   * for all argument counts
   * The function packs arguments in a vector<GenericValuePtr>, computes the
   * signature and bounce those to metaCall.
   */
  #define pushi(z, n,_) params.push_back(p ## n);
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params);      \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::async(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, MetaCallType_Queued);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      MetaCallType callType,                                              \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, callType);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #undef pushi

  template<typename T>
  qi::FutureSync<T> GenericObject::getProperty(const std::string& name)
  {
    int pid = metaObject().propertyId(name);
    if (pid < 0)
      return makeFutureError<T>("Property not found");
    qi::Future<GenericValue> f = type->getProperty(value, pid);
    qi::Promise<T> p;
    f.connect(boost::bind(&detail::futureAdapterVal<T>,_1, p));
    return p.future();
  }

  template<typename T>
  qi::FutureSync<void> GenericObject::setProperty(const std::string& name, const T& val)
  {
    int pid = metaObject().propertyId(name);
    if (pid < 0)
      return makeFutureError<void>("Property not found");
    return type->setProperty(value, pid, GenericValue(GenericValueRef(val)));
  }

  /* An ObjectPtr is actually of a Dynamic type: The underlying Type*
   * is not allways the same.
  */
  template<> class QITYPE_API TypeImpl<ObjectPtr>: public TypeDynamic
  {
  public:
    virtual GenericValuePtr get(void* storage)
    {
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(&storage);
      GenericValuePtr result;
      if (!*val)
      {
        return GenericValuePtr();
      }
      result.type = (*val)->type;
      result.value = (*val)->value;
      return result;
    }

    virtual void set(void** storage, GenericValuePtr source)
    {
      qiLogCategory("qitype.object");
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(storage);
      if (source.type->info() == info())
      { // source is objectptr
        ObjectPtr* src = (ObjectPtr*)source.type->ptrFromStorage(&source.value);
        if (!*src)
          qiLogWarning() << "NULL ObjectPtr";
        *val = *src;
      }
      else if (source.kind() == Type::Dynamic)
      { // try to dereference dynamic type in case it contains an object
        set(storage, source.asDynamic());
      }
      else if (source.kind() == Type::Object)
      { // wrap object in objectptr: we do not keep it alive,
        // but source type offers no tracking capability
        ObjectPtr op(new GenericObject(static_cast<ObjectType*>(source.type), source.value));
        *val = op;
      }
      else
        throw std::runtime_error((std::string)"Cannot assign non-object " + source.type->infoString() + " to ObjectPtr");

    }
    typedef DefaultTypeImplMethods<ObjectPtr> Methods;
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  namespace detail
  {
    typedef std::map<TypeInfo, boost::function<GenericValuePtr(ObjectPtr)> > ProxyGeneratorMap;
    QITYPE_API ProxyGeneratorMap& proxyGeneratorMap();

    template<typename Proxy>
    GenericValuePtr makeProxy(ObjectPtr ptr)
    {
      boost::shared_ptr<Proxy> sp(new Proxy(ptr));
      return GenericValuePtr(&sp).clone();
    }
  }
  template<typename Proxy>
  bool registerProxy()
  {
    detail::ProxyGeneratorMap& map = detail::proxyGeneratorMap();
    map[typeOf<Proxy>()->info()] = &detail::makeProxy<Proxy>;
    return true;
  }
}
#endif  // _QITYPE_DETAILS_GENERICOBJECT_HXX_
<commit_msg>GVP::toObject(): Accept a pointer.<commit_after>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_GENERICOBJECT_HXX_
#define _QITYPE_DETAILS_GENERICOBJECT_HXX_

#include <qi/future.hpp>
#include <qitype/typeobject.hpp>
#include <qitype/details/typeimpl.hxx>

namespace qi {

  namespace detail
  {

    template <typename T>
    inline void futureAdapter(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<T> promise)
    {

      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }

      GenericValuePtr val =  metaFut.value();
      Type* targetType = typeOf<T>();
      try
      {
        std::pair<GenericValuePtr, bool> conv = val.convert(targetType);
        if (!conv.first.type)
          promise.setError(std::string("Unable to convert call result to target type:")
            + val.type->infoString() + " -> " + targetType->infoString());
        else
        {
          T* res = (T*)conv.first.type->ptrFromStorage(&conv.first.value);
          promise.setValue(*res);
        }
        if (conv.second)
          conv.first.destroy();
      }
      catch(const std::exception& e)
      {
        promise.setError(std::string("Return argument conversion error: ") + e.what());
      }
      val.destroy();
    }

    template <typename T>
    inline void futureAdapterVal(qi::Future<qi::GenericValue> metaFut, qi::Promise<T> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      const GenericValue& val =  metaFut.value();
      try
      {
        promise.setValue(val.to<T>());
      }
      catch (const std::exception& e)
      {
        promise.setError(std::string("Return argument conversion error: ") + e.what());
      }
    }

    template<>
    inline void futureAdapterVal(qi::Future<qi::GenericValue> metaFut, qi::Promise<GenericValue> promise)
    {
      if (metaFut.hasError())
        promise.setError(metaFut.error());
      else
        promise.setValue(metaFut.value());
    }

    template <>
    inline void futureAdapter<void>(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<void> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      promise.setValue(0);
    }

  }

  /* Generate qi::FutureSync<R> GenericObject::call(methodname, args...)
   * for all argument counts
   * The function packs arguments in a vector<GenericValuePtr>, computes the
   * signature and bounce those to metaCall.
   */
  #define pushi(z, n,_) params.push_back(p ## n);
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params);      \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::async(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, MetaCallType_Queued);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      MetaCallType callType,                                              \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, callType);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #undef pushi

  template<typename T>
  qi::FutureSync<T> GenericObject::getProperty(const std::string& name)
  {
    int pid = metaObject().propertyId(name);
    if (pid < 0)
      return makeFutureError<T>("Property not found");
    qi::Future<GenericValue> f = type->getProperty(value, pid);
    qi::Promise<T> p;
    f.connect(boost::bind(&detail::futureAdapterVal<T>,_1, p));
    return p.future();
  }

  template<typename T>
  qi::FutureSync<void> GenericObject::setProperty(const std::string& name, const T& val)
  {
    int pid = metaObject().propertyId(name);
    if (pid < 0)
      return makeFutureError<void>("Property not found");
    return type->setProperty(value, pid, GenericValue(GenericValueRef(val)));
  }

  /* An ObjectPtr is actually of a Dynamic type: The underlying Type*
   * is not allways the same.
  */
  template<> class QITYPE_API TypeImpl<ObjectPtr>: public TypeDynamic
  {
  public:
    virtual GenericValuePtr get(void* storage)
    {
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(&storage);
      GenericValuePtr result;
      if (!*val)
      {
        return GenericValuePtr();
      }
      result.type = (*val)->type;
      result.value = (*val)->value;
      return result;
    }

    virtual void set(void** storage, GenericValuePtr source)
    {
      qiLogCategory("qitype.object");
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(storage);
      if (source.type->info() == info())
      { // source is objectptr
        ObjectPtr* src = (ObjectPtr*)source.type->ptrFromStorage(&source.value);
        if (!*src)
          qiLogWarning() << "NULL ObjectPtr";
        *val = *src;
      }
      else if (source.kind() == Type::Dynamic)
      { // try to dereference dynamic type in case it contains an object
        set(storage, source.asDynamic());
      }
      else if (source.kind() == Type::Object)
      { // wrap object in objectptr: we do not keep it alive,
        // but source type offers no tracking capability
        ObjectPtr op(new GenericObject(static_cast<ObjectType*>(source.type), source.value));
        *val = op;
      }
      else if (source.kind() == Type::Pointer)
      {
        TypePointer* ptype = static_cast<TypePointer*>(source.type);
        // FIXME: find a way!
        if (ptype->pointerKind() == TypePointer::Shared)
          qiLogInfo("ObjectPtr will *not* track original shared pointer");
        set(storage, *source);
      }
      else
        throw std::runtime_error((std::string)"Cannot assign non-object " + source.type->infoString() + " to ObjectPtr");

    }
    typedef DefaultTypeImplMethods<ObjectPtr> Methods;
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  namespace detail
  {
    typedef std::map<TypeInfo, boost::function<GenericValuePtr(ObjectPtr)> > ProxyGeneratorMap;
    QITYPE_API ProxyGeneratorMap& proxyGeneratorMap();

    template<typename Proxy>
    GenericValuePtr makeProxy(ObjectPtr ptr)
    {
      boost::shared_ptr<Proxy> sp(new Proxy(ptr));
      return GenericValuePtr(&sp).clone();
    }
  }
  template<typename Proxy>
  bool registerProxy()
  {
    detail::ProxyGeneratorMap& map = detail::proxyGeneratorMap();
    map[typeOf<Proxy>()->info()] = &detail::makeProxy<Proxy>;
    return true;
  }
}
#endif  // _QITYPE_DETAILS_GENERICOBJECT_HXX_
<|endoftext|>


<commit_before>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_GENERICOBJECT_HXX_
#define _QITYPE_DETAILS_GENERICOBJECT_HXX_

#include <qi/future.hpp>
#include <qitype/typeobject.hpp>
#include <qitype/details/typeimpl.hxx>

namespace qi {

  namespace detail
  {

    template <typename T>
    inline void futureAdapter(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<T> promise)
    {

      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }

      GenericValuePtr val =  metaFut.value();
      Type* targetType = typeOf<T>();
      std::pair<GenericValuePtr, bool> conv = val.convert(targetType);
      if (!conv.first.type)
        promise.setError(std::string("Unable to convert call result to target type:")
          + val.type->infoString() + " -> " + targetType->infoString());
      else
      {
        T* res = (T*)conv.first.type->ptrFromStorage(&conv.first.value);
        promise.setValue(*res);
      }
      if (conv.second)
        conv.first.destroy();
      val.destroy();
    }

    template <>
    inline void futureAdapter<void>(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<void> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      promise.setValue(0);
    }

  }

  /* Generate qi::FutureSync<R> GenericObject::call(methodname, args...)
   * for all argument counts
   * The function packs arguments in a vector<GenericValuePtr>, computes the
   * signature and bounce those to metaCall.
   */
  #define pushi(z, n,_) params.push_back(p ## n);
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params);      \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::async(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, MetaCallType_Queued);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      MetaCallType callType,                                              \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, callType);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #undef pushi

  /* An ObjectPtr is actually of a Dynamic type: The underlying Type*
   * is not allways the same.
  */
  template<> class TypeImpl<ObjectPtr>: public TypeDynamic
  {
  public:
    virtual std::pair<GenericValuePtr, bool> get(void* storage)
    {
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(&storage);
      GenericValuePtr result;
      result.type = (*val)->type;
      result.value = (*val)->value;
      return std::make_pair(result, false);
    }

    virtual void set(void** storage, GenericValuePtr source)
    {
      qiLogCategory("qitype.object");
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(storage);
      if (source.type->info() == info())
      {
        ObjectPtr* src = (ObjectPtr*)source.type->ptrFromStorage(&source.value);
        if (!*src)
          qiLogWarning() << "NULL ObjectPtr";
        *val = *src;
      }
      else if (source.kind() == Type::Dynamic)
      {
        std::pair<GenericValuePtr, bool> val
          = static_cast<TypeDynamic*>(source.type)->get(source.value);
       set(storage, val.first);
       if (val.second)
         val.first.destroy();
      }
      else if (source.kind() == Type::Object)
      {
        ObjectPtr op(new GenericObject(static_cast<ObjectType*>(source.type), source.value));
        *val = op;
      }
      else
        throw std::runtime_error((std::string)"Cannot assign non-object " + source.type->infoString() + " to ObjectPtr");

    }
    typedef DefaultTypeImplMethods<ObjectPtr> Methods;
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  namespace detail
  {
    typedef std::map<TypeInfo, boost::function<GenericValuePtr(ObjectPtr)> > ProxyGeneratorMap;
    QITYPE_API ProxyGeneratorMap& proxyGeneratorMap();

    template<typename Proxy>
    GenericValuePtr makeProxy(ObjectPtr ptr)
    {
      boost::shared_ptr<Proxy> sp(new Proxy(ptr));
      return GenericValuePtr::from(sp).clone();
    }
  }
  template<typename Proxy>
  bool registerProxy()
  {
    detail::ProxyGeneratorMap& map = detail::proxyGeneratorMap();
    map[typeOf<Proxy>()->info()] = &detail::makeProxy<Proxy>;
    return true;
  }
}
#endif  // _QITYPE_DETAILS_GENERICOBJECT_HXX_
<commit_msg>Fix ObjectPtr serialization: Add missing QITYPE_API.<commit_after>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_GENERICOBJECT_HXX_
#define _QITYPE_DETAILS_GENERICOBJECT_HXX_

#include <qi/future.hpp>
#include <qitype/typeobject.hpp>
#include <qitype/details/typeimpl.hxx>

namespace qi {

  namespace detail
  {

    template <typename T>
    inline void futureAdapter(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<T> promise)
    {

      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }

      GenericValuePtr val =  metaFut.value();
      Type* targetType = typeOf<T>();
      std::pair<GenericValuePtr, bool> conv = val.convert(targetType);
      if (!conv.first.type)
        promise.setError(std::string("Unable to convert call result to target type:")
          + val.type->infoString() + " -> " + targetType->infoString());
      else
      {
        T* res = (T*)conv.first.type->ptrFromStorage(&conv.first.value);
        promise.setValue(*res);
      }
      if (conv.second)
        conv.first.destroy();
      val.destroy();
    }

    template <>
    inline void futureAdapter<void>(qi::Future<qi::GenericValuePtr> metaFut, qi::Promise<void> promise)
    {
      //error handling
      if (metaFut.hasError()) {
        promise.setError(metaFut.error());
        return;
      }
      promise.setValue(0);
    }

  }

  /* Generate qi::FutureSync<R> GenericObject::call(methodname, args...)
   * for all argument counts
   * The function packs arguments in a vector<GenericValuePtr>, computes the
   * signature and bounce those to metaCall.
   */
  #define pushi(z, n,_) params.push_back(p ## n);
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params);      \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::async(             \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, MetaCallType_Queued);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                           \
  template<typename R> qi::FutureSync<R> GenericObject::call(             \
      MetaCallType callType,                                              \
      const std::string& methodName       comma                           \
      QI_GEN_ARGSDECLSAMETYPE(n, qi::AutoGenericValuePtr))             \
  {                                                                        \
     if (!value || !type) {                                                \
      return makeFutureError<R>("Invalid GenericObject");                  \
     }                                                                     \
     std::vector<qi::GenericValuePtr> params;                              \
     params.reserve(n);                                                    \
     BOOST_PP_REPEAT(n, pushi, _)                                          \
     std::string signature = methodName + "::(";                           \
     for (unsigned i=0; i< params.size(); ++i)                             \
       signature += params[i].signature();                                 \
     signature += ")";                                                     \
     std::string sigret;                                                   \
     qi::Promise<R> res;                                                   \
     qi::Future<GenericValuePtr> fmeta = metaCall(signature, params, callType);   \
     fmeta.connect(boost::bind<void>(&detail::futureAdapter<R>, _1, res));  \
     return res.future();                                                  \
  }

  QI_GEN(genCall)
  #undef genCall
  #undef pushi

  /* An ObjectPtr is actually of a Dynamic type: The underlying Type*
   * is not allways the same.
  */
  template<> class QITYPE_API TypeImpl<ObjectPtr>: public TypeDynamic
  {
  public:
    virtual std::pair<GenericValuePtr, bool> get(void* storage)
    {
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(&storage);
      GenericValuePtr result;
      result.type = (*val)->type;
      result.value = (*val)->value;
      return std::make_pair(result, false);
    }

    virtual void set(void** storage, GenericValuePtr source)
    {
      qiLogCategory("qitype.object");
      ObjectPtr* val = (ObjectPtr*)ptrFromStorage(storage);
      if (source.type->info() == info())
      {
        ObjectPtr* src = (ObjectPtr*)source.type->ptrFromStorage(&source.value);
        if (!*src)
          qiLogWarning() << "NULL ObjectPtr";
        *val = *src;
      }
      else if (source.kind() == Type::Dynamic)
      {
        std::pair<GenericValuePtr, bool> val
          = static_cast<TypeDynamic*>(source.type)->get(source.value);
       set(storage, val.first);
       if (val.second)
         val.first.destroy();
      }
      else if (source.kind() == Type::Object)
      {
        ObjectPtr op(new GenericObject(static_cast<ObjectType*>(source.type), source.value));
        *val = op;
      }
      else
        throw std::runtime_error((std::string)"Cannot assign non-object " + source.type->infoString() + " to ObjectPtr");

    }
    typedef DefaultTypeImplMethods<ObjectPtr> Methods;
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  namespace detail
  {
    typedef std::map<TypeInfo, boost::function<GenericValuePtr(ObjectPtr)> > ProxyGeneratorMap;
    QITYPE_API ProxyGeneratorMap& proxyGeneratorMap();

    template<typename Proxy>
    GenericValuePtr makeProxy(ObjectPtr ptr)
    {
      boost::shared_ptr<Proxy> sp(new Proxy(ptr));
      return GenericValuePtr::from(sp).clone();
    }
  }
  template<typename Proxy>
  bool registerProxy()
  {
    detail::ProxyGeneratorMap& map = detail::proxyGeneratorMap();
    map[typeOf<Proxy>()->info()] = &detail::makeProxy<Proxy>;
    return true;
  }
}
#endif  // _QITYPE_DETAILS_GENERICOBJECT_HXX_
<|endoftext|>


<commit_before>#include "kwsysPrivate.h"
#include KWSYS_HEADER(stl/vector)
#include KWSYS_HEADER(ios/sstream)
#include KWSYS_HEADER(ios/iostream)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "kwsys_stl_string.hxx.in"
# include "kwsys_stl_vector.h.in"
# include "kwsys_ios_sstream.h.in"
# include "kwsys_ios_iostream.h.in"
#endif

#include <string.h> /* strlen */

int testIOS(int, char*[])
{
  kwsys_ios::ostringstream ostr;
  const char hello[] = "hello";
  ostr << hello;
  if(ostr.str() != hello)
    {
    kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
    return 1;
    }
  const char world[] = "world";
  kwsys_ios::ostringstream ostr2;
  ostr2.write( hello, strlen(hello) ); /* I could do sizeof */
  ostr2.put( '\0' );
  ostr2.write( world, strlen(world) );
  if(ostr2.str().size() !=  strlen(hello) + 1 + strlen(world) )
    {
    kwsys_ios::cerr << "failed to write hello to ostr2" << kwsys_ios::endl;
    return 1;
    }
  kwsys_ios::istringstream istr(" 10 20 str ");
  kwsys_stl::string s;
  int x;
  if(istr >> x)
    {
    if(x != 10)
      {
      kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> x)
    {
    if(x != 20)
      {
      kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    if(s != "str")
      {
      kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
    return 1;
    }
  else
    {
    // Clear the failure.
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
    }
  istr.str("30");
  if(istr >> x)
    {
    if(x != 30)
      {
      kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::stringstream sstr;
  sstr << "40 str2";
  if(sstr >> x)
    {
    if(x != 40)
      {
      kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
    return 1;
    }
  if(sstr >> s)
    {
    if(s != "str2")
      {
      kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
  return 0;
}
<commit_msg>ENH: trying to reproduce issue on sunos<commit_after>#include "kwsysPrivate.h"
#include KWSYS_HEADER(stl/vector)
#include KWSYS_HEADER(ios/sstream)
#include KWSYS_HEADER(ios/iostream)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "kwsys_stl_string.hxx.in"
# include "kwsys_stl_vector.h.in"
# include "kwsys_ios_sstream.h.in"
# include "kwsys_ios_iostream.h.in"
#endif

#include <string.h> /* strlen */

int testIOS(int, char*[])
{
  kwsys_ios::ostringstream ostr;
  const char hello[] = "hello";
  ostr << hello;
  if(ostr.str() != hello)
    {
    kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
    return 1;
    }
  const char world[] = "world";
  kwsys_ios::ostringstream ostr2;
  ostr2.write( hello, strlen(hello) ); /* I could do sizeof */
  ostr2.put( '\0' );
  ostr2.write( world, strlen(world) );
  if(ostr2.str().size() !=  strlen(hello) + 1 + strlen(world) )
    {
    kwsys_ios::cerr << "failed to write hello to ostr2" << kwsys_ios::endl;
    return 1;
    }
  static const unsigned char array[] = { 0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x01,0x01,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x64,0x00,0x2c,0x00,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x49,0x54,0x4b,0x2f,0x47,0x44,0x43,0x4d,0x2f,0x4f,0x70,0x65,0x6e,0x4a,0x50,0x45,0x47,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0xff,0x90,0x00,0x0a,0x00,0x00,0x00,0x00,0x06,0x2c,0x00,0x01,0xff,0x93,0xcf,0xb0,0x18,0x08,0x7f,0xc6,0x99,0xbf,0xff,0xc0,0xf8,0xc1,0xc1,0xf3,0x05,0x81,0xf2,0x83,0x0a,0xa5,0xff,0x10,0x90,0xbf,0x2f,0xff,0x04,0xa8,0x7f,0xc0,0xf8,0xc4,0xc1,0xf3,0x09,0x81,0xf3,0x0c,0x19,0x34 };
  const unsigned int narray = sizeof(array); // 180
  kwsys_ios::stringstream strstr;
  strstr.write( (char*)array, narray );
  if(strstr.str().size() != narray )
    {
    kwsys_ios::cerr << "failed to write array to strstr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::istringstream istr(" 10 20 str ");
  kwsys_stl::string s;
  int x;
  if(istr >> x)
    {
    if(x != 10)
      {
      kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> x)
    {
    if(x != 20)
      {
      kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    if(s != "str")
      {
      kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
    return 1;
    }
  else
    {
    // Clear the failure.
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
    }
  istr.str("30");
  if(istr >> x)
    {
    if(x != 30)
      {
      kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::stringstream sstr;
  sstr << "40 str2";
  if(sstr >> x)
    {
    if(x != 40)
      {
      kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
    return 1;
    }
  if(sstr >> s)
    {
    if(s != "str2")
      {
      kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
  return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRenderViewBase.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkRenderViewBase.h"

#include "vtkCamera.h"
#include "vtkCommand.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include "vtkInteractorStyleRubberBand3D.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRendererCollection.h"
#include "vtkDataRepresentation.h"

vtkStandardNewMacro(vtkRenderViewBase);

vtkRenderViewBase::vtkRenderViewBase()
{
  this->RenderOnMouseMove = false;
  this->InteractionMode = -1;
  this->Renderer = vtkSmartPointer<vtkRenderer>::New();
  this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  this->RenderWindow->AddRenderer(this->Renderer);

  // We will handle all interactor renders by turning off rendering
  // in the interactor and listening to the interactor's render event.
  vtkSmartPointer<vtkRenderWindowInteractor> iren =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  iren->EnableRenderOff();
  iren->AddObserver(vtkCommand::RenderEvent, this->GetObserver());
  iren->AddObserver(vtkCommand::StartInteractionEvent, this->GetObserver());
  iren->AddObserver(vtkCommand::EndInteractionEvent, this->GetObserver());
  this->RenderWindow->SetInteractor(iren);
  this->SetInteractionMode(INTERACTION_MODE_2D);
}

vtkRenderViewBase::~vtkRenderViewBase()
{
}

vtkRenderer* vtkRenderViewBase::GetRenderer()
{
  return this->Renderer;
}

vtkRenderWindow* vtkRenderViewBase::GetRenderWindow()
{
  return this->RenderWindow;
}

void vtkRenderViewBase::SetRenderWindow(vtkRenderWindow* win)
{
  if (!win)
    {
    vtkErrorMacro(<< "SetRenderWindow called with a null window pointer."
                  << " That can't be right.");
    return;
    }

  // get rid of the render observer on the current window
  if (this->RenderWindow)
    {
    this->RenderWindow->RemoveObserver(this->GetObserver());
    }

  // move renderers to new window
  vtkRendererCollection* rens = this->RenderWindow->GetRenderers();
  while(rens->GetNumberOfItems())
    {
    vtkRenderer* ren = rens->GetFirstRenderer();
    ren->SetRenderWindow(NULL);
    win->AddRenderer(ren);
    this->RenderWindow->RemoveRenderer(ren);
    }

  // move interactor to new window
  vtkSmartPointer<vtkRenderWindowInteractor> iren =
      this->RenderWindow->GetInteractor();
  this->RenderWindow->SetInteractor(NULL);
  iren->SetRenderWindow(NULL);
  win->SetInteractor(iren);
  iren->SetRenderWindow(win);

  this->RenderWindow->UnRegister(this);
  this->RenderWindow = win;
  this->RenderWindow->Register(this);
  this->RenderWindow->AddObserver(vtkCommand::EndEvent, this->GetObserver());
}

vtkRenderWindowInteractor* vtkRenderViewBase::GetInteractor()
{
  return this->RenderWindow->GetInteractor();
}

void vtkRenderViewBase::SetInteractor(vtkRenderWindowInteractor* interactor)
{
  if (!interactor)
    {
    vtkErrorMacro(<< "SetInteractor called with a null interactor pointer."
                  << " That can't be right.");
    return;
    }

  // get rid of the render observer on any current interactor
  if (this->RenderWindow->GetInteractor())
    {
    this->RenderWindow->GetInteractor()->RemoveObserver(this->GetObserver());
    }

  // We need to preserve the interactor style currently present on the
  // interactor.
  vtkInteractorObserver *oldStyle = this->GetInteractorStyle();
  oldStyle->Register(this);

  // We will handle all interactor renders by turning off rendering
  // in the interactor and listening to the interactor's render event.
  interactor->EnableRenderOff();
  interactor->AddObserver(vtkCommand::RenderEvent, this->GetObserver());
  interactor->AddObserver(vtkCommand::StartInteractionEvent, this->GetObserver());
  interactor->AddObserver(vtkCommand::EndInteractionEvent, this->GetObserver());
  this->RenderWindow->SetInteractor(interactor);
  interactor->SetInteractorStyle(oldStyle);
  oldStyle->UnRegister(this);
}

vtkInteractorObserver* vtkRenderViewBase::GetInteractorStyle()
{
  return this->GetInteractor()->GetInteractorStyle();
}

void vtkRenderViewBase::SetInteractorStyle(vtkInteractorObserver* style)
{
  if (!style)
    {
    vtkErrorMacro("Interactor style must not be null.");
    return;
    }
  vtkInteractorObserver* oldStyle = this->GetInteractorStyle();
  if (style != oldStyle)
    {
    if (oldStyle)
      {
      oldStyle->RemoveObserver(this->GetObserver());
      }
    this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
    style->AddObserver(
      vtkCommand::SelectionChangedEvent, this->GetObserver());
    vtkInteractorStyleRubberBand2D* style2D =
      vtkInteractorStyleRubberBand2D::SafeDownCast(style);
    vtkInteractorStyleRubberBand3D* style3D =
      vtkInteractorStyleRubberBand3D::SafeDownCast(style);
    if (style2D)
      {
      style2D->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      this->InteractionMode = INTERACTION_MODE_2D;
      }
    else if (style3D)
      {
      style3D->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      this->InteractionMode = INTERACTION_MODE_3D;
      }
    else
      {
      this->InteractionMode = INTERACTION_MODE_UNKNOWN;
      }
    }
}

void vtkRenderViewBase::SetInteractionMode(int mode)
{
  if (this->InteractionMode != mode)
    {
    this->InteractionMode = mode;
    vtkInteractorObserver* oldStyle = this->GetInteractor()->GetInteractorStyle();
    if (mode == INTERACTION_MODE_2D)
      {
      if (oldStyle)
        {
        oldStyle->RemoveObserver(this->GetObserver());
        }
      vtkInteractorStyleRubberBand2D* style = vtkInteractorStyleRubberBand2D::New();
      this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
      style->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      style->AddObserver(vtkCommand::SelectionChangedEvent, this->GetObserver());
      this->Renderer->GetActiveCamera()->ParallelProjectionOn();
      style->Delete();
      }
    else if (mode == INTERACTION_MODE_3D)
      {
      if (oldStyle)
        {
        oldStyle->RemoveObserver(this->GetObserver());
        }
      vtkInteractorStyleRubberBand3D* style = vtkInteractorStyleRubberBand3D::New();
      this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
      style->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      style->AddObserver(vtkCommand::SelectionChangedEvent, this->GetObserver());
      this->Renderer->GetActiveCamera()->ParallelProjectionOff();
      style->Delete();
      }
    else
      {
      vtkErrorMacro("Unknown interaction mode.");
      }
    }
}

void vtkRenderViewBase::SetRenderOnMouseMove(bool b)
{
  if (b == this->RenderOnMouseMove)
    {
    return;
    }

  vtkInteractorObserver* style = this->GetInteractor()->GetInteractorStyle();
  vtkInteractorStyleRubberBand2D* style2D =
    vtkInteractorStyleRubberBand2D::SafeDownCast(style);
  if (style2D)
    {
    style2D->SetRenderOnMouseMove(b);
    }
  vtkInteractorStyleRubberBand3D* style3D =
    vtkInteractorStyleRubberBand3D::SafeDownCast(style);
  if (style3D)
    {
    style3D->SetRenderOnMouseMove(b);
    }
  this->RenderOnMouseMove = b;
}

void vtkRenderViewBase::Render()
{
  // Indirectly call this->RenderWindow->Start() without crashing.
  // to create context if it is not yet created and to make it current
  // this is required for HoverWidget to be active after the first
  // render.
  this->RenderWindow->GetInteractor()->Initialize();

  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCameraClippingRange();
  this->RenderWindow->Render();
}

void vtkRenderViewBase::ResetCamera()
{
  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCamera();
}

void vtkRenderViewBase::ResetCameraClippingRange()
{
  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCameraClippingRange();
}

void vtkRenderViewBase::PrepareForRendering()
{
  this->Update();
}

void vtkRenderViewBase::ProcessEvents(
  vtkObject* caller, unsigned long eventId, void* callData)
{
  if (caller == this->GetInteractor() && eventId == vtkCommand::RenderEvent)
    {
    vtkDebugMacro(<< "interactor causing a render event.");
    this->Render();
    }
  if (vtkDataRepresentation::SafeDownCast(caller) &&
      eventId == vtkCommand::SelectionChangedEvent)
    {
    vtkDebugMacro("selection changed causing a render event");
    this->Render();
    }
  else if (vtkDataRepresentation::SafeDownCast(caller) &&
           eventId == vtkCommand::UpdateEvent)
    {
    // UpdateEvent is called from push pipeline executions from
    // vtkExecutionScheduler. We want to automatically render the view
    // when one of our representations is updated.
    vtkDebugMacro("push pipeline causing a render event");
    this->Render();
    }
  this->Superclass::ProcessEvents(caller, eventId, callData);
}

void vtkRenderViewBase::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "RenderWindow: ";
  if (this->RenderWindow)
    {
    os << "\n";
    this->RenderWindow->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
  os << indent << "Renderer: ";
  if (this->Renderer)
    {
    os << "\n";
    this->Renderer->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
  os << indent << "InteractionMode: " << this->InteractionMode << endl;
  os << indent << "RenderOnMouseMove: " << this->RenderOnMouseMove << endl;
}
<commit_msg>BUG: FIXME: vtkRenderViewBase::Interactor.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRenderViewBase.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkRenderViewBase.h"

#include "vtkCamera.h"
#include "vtkCommand.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include "vtkInteractorStyleRubberBand3D.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRendererCollection.h"
#include "vtkDataRepresentation.h"

vtkStandardNewMacro(vtkRenderViewBase);

vtkRenderViewBase::vtkRenderViewBase()
{
  this->RenderOnMouseMove = false;
  this->InteractionMode = -1;
  this->Renderer = vtkSmartPointer<vtkRenderer>::New();
  this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  this->RenderWindow->AddRenderer(this->Renderer);

  // We will handle all interactor renders by turning off rendering
  // in the interactor and listening to the interactor's render event.
  vtkSmartPointer<vtkRenderWindowInteractor> iren =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  iren->EnableRenderOff();
  iren->AddObserver(vtkCommand::RenderEvent, this->GetObserver());
  iren->AddObserver(vtkCommand::StartInteractionEvent, this->GetObserver());
  iren->AddObserver(vtkCommand::EndInteractionEvent, this->GetObserver());
  this->RenderWindow->SetInteractor(iren);
  this->SetInteractionMode(INTERACTION_MODE_2D);
}

vtkRenderViewBase::~vtkRenderViewBase()
{
}

vtkRenderer* vtkRenderViewBase::GetRenderer()
{
  return this->Renderer;
}

vtkRenderWindow* vtkRenderViewBase::GetRenderWindow()
{
  return this->RenderWindow;
}

void vtkRenderViewBase::SetRenderWindow(vtkRenderWindow* win)
{
  if (!win)
    {
    vtkErrorMacro(<< "SetRenderWindow called with a null window pointer."
                  << " That can't be right.");
    return;
    }

  // get rid of the render observer on the current window
  if (this->RenderWindow)
    {
    this->RenderWindow->RemoveObserver(this->GetObserver());
    }

  // move renderers to new window
  vtkRendererCollection* rens = this->RenderWindow->GetRenderers();
  while(rens->GetNumberOfItems())
    {
    vtkRenderer* ren = rens->GetFirstRenderer();
    ren->SetRenderWindow(NULL);
    win->AddRenderer(ren);
    this->RenderWindow->RemoveRenderer(ren);
    }

  // move interactor to new window
  // FIXME: Qt doesn't like interactor being initialized here.
  //vtkSmartPointer<vtkRenderWindowInteractor> iren =
  //    this->RenderWindow->GetInteractor();
  //this->RenderWindow->SetInteractor(NULL);
  //iren->SetRenderWindow(NULL);
  //win->SetInteractor(iren);
  //iren->SetRenderWindow(win);

  this->RenderWindow->UnRegister(this);
  this->RenderWindow = win;
  this->RenderWindow->Register(this);
  this->RenderWindow->AddObserver(vtkCommand::EndEvent, this->GetObserver());
}

vtkRenderWindowInteractor* vtkRenderViewBase::GetInteractor()
{
  return this->RenderWindow->GetInteractor();
}

void vtkRenderViewBase::SetInteractor(vtkRenderWindowInteractor* interactor)
{
  if (!interactor)
    {
    vtkErrorMacro(<< "SetInteractor called with a null interactor pointer."
                  << " That can't be right.");
    return;
    }

  // get rid of the render observer on any current interactor
  if (this->RenderWindow->GetInteractor())
    {
    this->RenderWindow->GetInteractor()->RemoveObserver(this->GetObserver());
    }

  // We need to preserve the interactor style currently present on the
  // interactor.
  vtkInteractorObserver *oldStyle = this->GetInteractorStyle();
  oldStyle->Register(this);

  // We will handle all interactor renders by turning off rendering
  // in the interactor and listening to the interactor's render event.
  interactor->EnableRenderOff();
  interactor->AddObserver(vtkCommand::RenderEvent, this->GetObserver());
  interactor->AddObserver(vtkCommand::StartInteractionEvent, this->GetObserver());
  interactor->AddObserver(vtkCommand::EndInteractionEvent, this->GetObserver());
  this->RenderWindow->SetInteractor(interactor);
  interactor->SetInteractorStyle(oldStyle);
  oldStyle->UnRegister(this);
}

vtkInteractorObserver* vtkRenderViewBase::GetInteractorStyle()
{
  return this->GetInteractor()->GetInteractorStyle();
}

void vtkRenderViewBase::SetInteractorStyle(vtkInteractorObserver* style)
{
  if (!style)
    {
    vtkErrorMacro("Interactor style must not be null.");
    return;
    }
  vtkInteractorObserver* oldStyle = this->GetInteractorStyle();
  if (style != oldStyle)
    {
    if (oldStyle)
      {
      oldStyle->RemoveObserver(this->GetObserver());
      }
    this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
    style->AddObserver(
      vtkCommand::SelectionChangedEvent, this->GetObserver());
    vtkInteractorStyleRubberBand2D* style2D =
      vtkInteractorStyleRubberBand2D::SafeDownCast(style);
    vtkInteractorStyleRubberBand3D* style3D =
      vtkInteractorStyleRubberBand3D::SafeDownCast(style);
    if (style2D)
      {
      style2D->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      this->InteractionMode = INTERACTION_MODE_2D;
      }
    else if (style3D)
      {
      style3D->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      this->InteractionMode = INTERACTION_MODE_3D;
      }
    else
      {
      this->InteractionMode = INTERACTION_MODE_UNKNOWN;
      }
    }
}

void vtkRenderViewBase::SetInteractionMode(int mode)
{
  if (this->InteractionMode != mode)
    {
    this->InteractionMode = mode;
    vtkInteractorObserver* oldStyle = this->GetInteractor()->GetInteractorStyle();
    if (mode == INTERACTION_MODE_2D)
      {
      if (oldStyle)
        {
        oldStyle->RemoveObserver(this->GetObserver());
        }
      vtkInteractorStyleRubberBand2D* style = vtkInteractorStyleRubberBand2D::New();
      this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
      style->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      style->AddObserver(vtkCommand::SelectionChangedEvent, this->GetObserver());
      this->Renderer->GetActiveCamera()->ParallelProjectionOn();
      style->Delete();
      }
    else if (mode == INTERACTION_MODE_3D)
      {
      if (oldStyle)
        {
        oldStyle->RemoveObserver(this->GetObserver());
        }
      vtkInteractorStyleRubberBand3D* style = vtkInteractorStyleRubberBand3D::New();
      this->RenderWindow->GetInteractor()->SetInteractorStyle(style);
      style->SetRenderOnMouseMove(this->GetRenderOnMouseMove());
      style->AddObserver(vtkCommand::SelectionChangedEvent, this->GetObserver());
      this->Renderer->GetActiveCamera()->ParallelProjectionOff();
      style->Delete();
      }
    else
      {
      vtkErrorMacro("Unknown interaction mode.");
      }
    }
}

void vtkRenderViewBase::SetRenderOnMouseMove(bool b)
{
  if (b == this->RenderOnMouseMove)
    {
    return;
    }

  vtkInteractorObserver* style = this->GetInteractor()->GetInteractorStyle();
  vtkInteractorStyleRubberBand2D* style2D =
    vtkInteractorStyleRubberBand2D::SafeDownCast(style);
  if (style2D)
    {
    style2D->SetRenderOnMouseMove(b);
    }
  vtkInteractorStyleRubberBand3D* style3D =
    vtkInteractorStyleRubberBand3D::SafeDownCast(style);
  if (style3D)
    {
    style3D->SetRenderOnMouseMove(b);
    }
  this->RenderOnMouseMove = b;
}

void vtkRenderViewBase::Render()
{
  // Indirectly call this->RenderWindow->Start() without crashing.
  // to create context if it is not yet created and to make it current
  // this is required for HoverWidget to be active after the first
  // render.
  this->RenderWindow->GetInteractor()->Initialize();

  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCameraClippingRange();
  this->RenderWindow->Render();
}

void vtkRenderViewBase::ResetCamera()
{
  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCamera();
}

void vtkRenderViewBase::ResetCameraClippingRange()
{
  this->Update();
  this->PrepareForRendering();
  this->Renderer->ResetCameraClippingRange();
}

void vtkRenderViewBase::PrepareForRendering()
{
  this->Update();
}

void vtkRenderViewBase::ProcessEvents(
  vtkObject* caller, unsigned long eventId, void* callData)
{
  if (caller == this->GetInteractor() && eventId == vtkCommand::RenderEvent)
    {
    vtkDebugMacro(<< "interactor causing a render event.");
    this->Render();
    }
  if (vtkDataRepresentation::SafeDownCast(caller) &&
      eventId == vtkCommand::SelectionChangedEvent)
    {
    vtkDebugMacro("selection changed causing a render event");
    this->Render();
    }
  else if (vtkDataRepresentation::SafeDownCast(caller) &&
           eventId == vtkCommand::UpdateEvent)
    {
    // UpdateEvent is called from push pipeline executions from
    // vtkExecutionScheduler. We want to automatically render the view
    // when one of our representations is updated.
    vtkDebugMacro("push pipeline causing a render event");
    this->Render();
    }
  this->Superclass::ProcessEvents(caller, eventId, callData);
}

void vtkRenderViewBase::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "RenderWindow: ";
  if (this->RenderWindow)
    {
    os << "\n";
    this->RenderWindow->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
  os << indent << "Renderer: ";
  if (this->Renderer)
    {
    os << "\n";
    this->Renderer->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
  os << indent << "InteractionMode: " << this->InteractionMode << endl;
  os << indent << "RenderOnMouseMove: " << this->RenderOnMouseMove << endl;
}
<|endoftext|>


<commit_before><commit_msg>`yli::config::SettingMaster`: cleaning up code.<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix: `get_ground_level`: `position.x`, `position.z` coordinate check.<commit_after><|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "classad/common.h"
#include "classad/util.h"
#include <limits.h>

using namespace std;

#if HAVE_LONG_TIMEZONE
extern DLL_IMPORT_MAGIC long timezone;
#endif

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#if HAVE_LONG_TIMEZONE
    return ::timezone;
#else
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					unsigned int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

void day_numbers(int year, int month, int day, int &weekday, int &yearday)
{
    int fixed =       fixed_from_gregorian(year, month, day);
    int jan1_fixed =  fixed_from_gregorian(year, 1, 1);
    weekday = fixed % 7;
    yearday = fixed - jan1_fixed;
    return;
}

int fixed_from_gregorian(int year, int month, int day)
{
    int fixed;
    int month_adjustment;

    if (month <= 2) {
        month_adjustment = 0;
    } else if (is_leap_year(year)) {
        month_adjustment = -1;
    } else {
        month_adjustment = -2;
    }
    fixed = 365 * (year -1)
          + ((year - 1) / 4)
          - ((year - 1) / 100)
          + ((year - 1) / 400)
          + ((367 * month - 362) / 12)
          + month_adjustment
          + day;
    return fixed;
}

bool is_leap_year(int year)
{
    int  mod4;
    int  mod400;
    bool leap_year;

    mod4   = year % 4;
    mod400 = year % 400;

    if (mod4 == 0 && mod400 != 100 && mod400 != 200 && mod400 != 300) {
        leap_year = true;
    } else {
        leap_year = false;
    }
    return leap_year;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    if (!isinf(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad

<commit_msg>Fixing compiler problems for Mac OS.  Forgot to include config.h.<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "classad/common.h"
#include "classad/util.h"
#include "config.h"
#include <limits.h>

using namespace std;

#if HAVE_LONG_TIMEZONE
extern DLL_IMPORT_MAGIC long timezone;
#endif

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#if HAVE_LONG_TIMEZONE
    return ::timezone;
#else
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					unsigned int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

void day_numbers(int year, int month, int day, int &weekday, int &yearday)
{
    int fixed =       fixed_from_gregorian(year, month, day);
    int jan1_fixed =  fixed_from_gregorian(year, 1, 1);
    weekday = fixed % 7;
    yearday = fixed - jan1_fixed;
    return;
}

int fixed_from_gregorian(int year, int month, int day)
{
    int fixed;
    int month_adjustment;

    if (month <= 2) {
        month_adjustment = 0;
    } else if (is_leap_year(year)) {
        month_adjustment = -1;
    } else {
        month_adjustment = -2;
    }
    fixed = 365 * (year -1)
          + ((year - 1) / 4)
          - ((year - 1) / 100)
          + ((year - 1) / 400)
          + ((367 * month - 362) / 12)
          + month_adjustment
          + day;
    return fixed;
}

bool is_leap_year(int year)
{
    int  mod4;
    int  mod400;
    bool leap_year;

    mod4   = year % 4;
    mod400 = year % 400;

    if (mod4 == 0 && mod400 != 100 && mod400 != 200 && mod400 != 300) {
        leap_year = true;
    } else {
        leap_year = false;
    }
    return leap_year;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    if (!isinf(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad

<|endoftext|>


<commit_before>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "mainwindow.h"

#include <qitemselectionmodel.h>
#include <qplaintextedit.h>
#include <qstring.h>
#include <qtreeview.h>

#include "kdeaccessibilityclient/registry.h"
#include "kdeaccessibilityclient/accessibleobject.h"

#include "accessibletree.h"

#include "tests_auto_modeltest_modeltest.h"

using namespace KAccessibleClient;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), m_model(0)
{
    ui.setupUi(this);

    m_registry = new KAccessibleClient::Registry(this);
    connect(m_registry, SIGNAL(focusChanged(KAccessibleClient::AccessibleObject)), this, SLOT(focusChanged(KAccessibleClient::AccessibleObject)));
    m_registry->subscribeEventListeners(KAccessibleClient::Registry::Focus);

    m_model = new AccessibleTree(this);
    ui.treeView->setModel(m_model);
    ui.treeView->setContextMenuPolicy(Qt::ActionsContextMenu);
    m_model->setRegistry(m_registry);

    // The ultimate model verificaton helper :p
    new ModelTest(m_model, this);

    connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectionChanged(QModelIndex,QModelIndex)));
    connect(ui.action_Reset_tree, SIGNAL(triggered()), m_model, SLOT(resetModel()));
    ui.action_Reset_tree->setShortcut(QKeySequence(QKeySequence::Refresh));
}

void MainWindow::focusChanged(const KAccessibleClient::AccessibleObject &object)
{
    ui.label->setText(tr("Focus changed to: %1 - %2 (%3)").arg(object.name()).arg(object.roleName()).arg(object.role()));

    if (ui.action_Follow_Focus->isChecked()) {
        QModelIndex index = m_model->indexForAccessible(object);
        if (index.isValid()) {
            ui.treeView->scrollTo(index);
            ui.treeView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
        }
    }
}

void MainWindow::selectionChanged(const QModelIndex& current, const QModelIndex&)
{
    QString text;

    while(!actions().isEmpty()) {
        ui.treeView->removeAction(actions().first());
    }

    if (current.isValid() && current.internalPointer()) {
        KAccessibleClient::AccessibleObject acc = static_cast<AccessibleWrapper*>(current.internalPointer())->acc;
        text += acc.name() + " (" + acc.description() + ")\n";
        text += "role: " + acc.roleName() + "\n";
        text += "checked: " + (acc.isChecked() ? QLatin1String("yes") : QLatin1String("no")) + '\n';

        text += "\nchildCount: " + QString::number(acc.childCount()) + "\n";
        foreach (const KAccessibleClient::AccessibleObject &child, acc.children()) {
            text += "child: " + child.name() + " (" + child.roleName() + ")\n";
        }

        Q_FOREACH(QAction *a, acc.actions()) {
            ui.treeView->insertAction(0, a);
        }
    }

    ui.plainTextEdit->setPlainText(text);
}

#include <mainwindow.moc>

<commit_msg>proper compile<commit_after>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "mainwindow.h"

#include <qitemselectionmodel.h>
#include <qplaintextedit.h>
#include <qstring.h>
#include <qtreeview.h>

#include "kdeaccessibilityclient/registry.h"
#include "kdeaccessibilityclient/accessibleobject.h"

#include "accessibletree.h"

#include "tests_auto_modeltest_modeltest.h"

using namespace KAccessibleClient;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), m_model(0)
{
    ui.setupUi(this);

    m_registry = new KAccessibleClient::Registry(this);
    connect(m_registry, SIGNAL(focusChanged(KAccessibleClient::AccessibleObject)), this, SLOT(focusChanged(KAccessibleClient::AccessibleObject)));
    m_registry->subscribeEventListeners(KAccessibleClient::Registry::Focus);

    m_model = new AccessibleTree(this);
    ui.treeView->setModel(m_model);
    ui.treeView->setContextMenuPolicy(Qt::ActionsContextMenu);
    m_model->setRegistry(m_registry);

    // The ultimate model verificaton helper :p
    new ModelTest(m_model, this);

    connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectionChanged(QModelIndex,QModelIndex)));
    connect(ui.action_Reset_tree, SIGNAL(triggered()), m_model, SLOT(resetModel()));
    ui.action_Reset_tree->setShortcut(QKeySequence(QKeySequence::Refresh));
}

void MainWindow::focusChanged(const KAccessibleClient::AccessibleObject &object)
{
    ui.label->setText(tr("Focus changed to: %1 - %2 (%3)").arg(object.name()).arg(object.roleName()).arg(object.role()));

    if (ui.action_Follow_Focus->isChecked()) {
        QModelIndex index = m_model->indexForAccessible(object);
        if (index.isValid()) {
            ui.treeView->scrollTo(index);
            ui.treeView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
        }
    }
}

void MainWindow::selectionChanged(const QModelIndex& current, const QModelIndex&)
{
    QString text;

    while(!actions().isEmpty()) {
        ui.treeView->removeAction(actions().first());
    }

    if (current.isValid() && current.internalPointer()) {
        KAccessibleClient::AccessibleObject acc = static_cast<AccessibleWrapper*>(current.internalPointer())->acc;
        text += acc.name() + " (" + acc.description() + ")\n";
        text += "role: " + acc.roleName() + "\n";
        text += "checked: " + (acc.isChecked() ? QLatin1String("yes") : QLatin1String("no")) + '\n';

        text += "\nchildCount: " + QString::number(acc.childCount()) + "\n";
        foreach (const KAccessibleClient::AccessibleObject &child, acc.children()) {
            text += "child: " + child.name() + " (" + child.roleName() + ")\n";
        }

        Q_FOREACH(QAction *a, acc.actions()) {
            ui.treeView->insertAction(0, a);
        }
    }

    ui.plainTextEdit->setPlainText(text);
}
<|endoftext|>


<commit_before>#include "FileUtils.hpp"
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>
#include <sstream>
#include <limits>
#include <cstring>

bool fileExists(const std::string& file) {
    struct stat buf;
    return (stat(file.c_str(), &buf) == 0);
}

uint64_t parseUint64(const std::string& value) {
    uint64_t ret;
    std::stringstream ss(value);
    ss >> ret;
    if(ss.fail()) {
        return std::numeric_limits<uint64_t>::max();
    }
    return ret;
}

#include <iostream>
using namespace std;
size_t getFilesize(const char* filename) {
    struct stat st;
    if(stat(filename, &st) != 0) {
        return std::numeric_limits<size_t>::max();
    }
    return st.st_size;
}
size_t getDirectoryFilesize(const char* dirname) {
    /**
     * Using boost::filesystem would make this task easier,
     * however it would introduce a large, clunky dependency
     * which is not practicable for all applications YakDB is
     * designed for.
     */
    DIR* dir;
    struct dirent* ent;
    size_t filesizeSum = 0;
    if ((dir = opendir(dirname)) != nullptr) {
        //Iterate over entries in directory
        while ((ent = readdir(dir)) != nullptr) {
            //ent->d_name is relative to the current directory.
            //Make it absolute
            std::string absoluteFilename =
                std::string(dirname) + "/" + std::string(ent->d_name);
            if(ent->d_type == DT_DIR) {
                //Skip . and .. which lead to infinite recursion
                if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) {
                    continue;
                }
                //Recurse into directory
                filesizeSum += getDirectoryFilesize(absoluteFilename.c_str());
            } else if(ent->d_type == DT_REG) {
                //Regular file -> use its size
                size_t filesize = getFilesize(absoluteFilename.c_str());
                //getFilesize returns max() on error
                if(filesize == std::numeric_limits<size_t>::max()) {
                    filesize = 0;
                }
                filesizeSum += filesize;
            } //Else: Ignore
        }
        closedir (dir);
    }
    return filesizeSum;
}<commit_msg>Remove FileUtils debugging code<commit_after>#include "FileUtils.hpp"
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>
#include <sstream>
#include <limits>
#include <cstring>

bool fileExists(const std::string& file) {
    struct stat buf;
    return (stat(file.c_str(), &buf) == 0);
}

uint64_t parseUint64(const std::string& value) {
    uint64_t ret;
    std::stringstream ss(value);
    ss >> ret;
    if(ss.fail()) {
        return std::numeric_limits<uint64_t>::max();
    }
    return ret;
}

size_t getFilesize(const char* filename) {
    struct stat st;
    if(stat(filename, &st) != 0) {
        return std::numeric_limits<size_t>::max();
    }
    return st.st_size;
}
size_t getDirectoryFilesize(const char* dirname) {
    /**
     * Using boost::filesystem would make this task easier,
     * however it would introduce a large, clunky dependency
     * which is not practicable for all applications YakDB is
     * designed for.
     */
    DIR* dir;
    struct dirent* ent;
    size_t filesizeSum = 0;
    if ((dir = opendir(dirname)) != nullptr) {
        //Iterate over entries in directory
        while ((ent = readdir(dir)) != nullptr) {
            //ent->d_name is relative to the current directory.
            //Make it absolute
            std::string absoluteFilename =
                std::string(dirname) + "/" + std::string(ent->d_name);
            if(ent->d_type == DT_DIR) {
                //Skip . and .. which lead to infinite recursion
                if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) {
                    continue;
                }
                //Recurse into directory
                filesizeSum += getDirectoryFilesize(absoluteFilename.c_str());
            } else if(ent->d_type == DT_REG) {
                //Regular file -> use its size
                size_t filesize = getFilesize(absoluteFilename.c_str());
                //getFilesize returns max() on error
                if(filesize == std::numeric_limits<size_t>::max()) {
                    filesize = 0;
                }
                filesizeSum += filesize;
            } //Else: Ignore
        }
        closedir (dir);
    }
    return filesizeSum;
}<|endoftext|>