<commit_before>#pragma once

#include "seq.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>
#include <vector>

namespace imu {

  namespace ty {

    template<typename mixin = no_mixin>
    struct base_node {

      typedef std::shared_ptr<base_node> p;

      mixin _mixin;

      virtual ~base_node()
      {}
    };

    template<typename mixin = no_mixin>
    struct basic_node : public base_node<mixin> {

      typedef std::shared_ptr<basic_node> p;
      typedef typename base_node<mixin>::p base;

      std::vector<base> _arr;

      inline basic_node()
        : _arr(32)
      {}

      inline basic_node(const base& root, const base& node)
        : basic_node()
      {
        _arr[0] = root;
        _arr[1] = node;
      }

      inline basic_node(const base& child)
        : basic_node()
      {
        _arr[0] = child;
      }

      static inline base new_path(uint64_t level, const base& node) {

        base out(node);
        for(auto l = level; level != 0; level -= 5) {
          out = base(nu<basic_node>(out));
        }
        return out;
      }

      static inline p push_tail(
          uint64_t cnt
        , uint64_t level
        , const p& parent
        , const base& tail) {

        p out(nu<basic_node>(*parent));
        base insert;

        uint64_t idx = ((cnt - 1) >> level) & 0x01f;

        if (level == 5) {
          insert = tail;
        }
        else {
          auto child = parent->_arr[idx];
          if (child) {
            auto as_base = std::dynamic_pointer_cast<basic_node>(child);
            insert = push_tail(cnt, level - 5, as_base, tail);
          }
          else {
            insert = new_path(level - 5, tail);
          }
        }

        out->_arr[idx] = insert;

        return out;
      }
    };

    template<typename Value, typename mixin = no_mixin>
    struct basic_leaf : public base_node<mixin> {

      typedef std::shared_ptr<basic_leaf> p;
      typedef base_node<mixin> base;

      std::vector<typename Value::p> _arr;

      inline basic_leaf()
      {}

      inline basic_leaf(const basic_leaf::p& a)
        : _arr(a->_arr)
      {}

      inline basic_leaf(const typename Value::p& val)
      { _arr.push_back(val); }

      inline const value::p& operator[](uint64_t n) const {
        return _arr[n];
      }
    };

    template<
        typename Value = value
      , typename mixin = no_mixin
      , typename node  = basic_node<>
      , typename leaf  = basic_leaf<Value>
      >
    struct basic_vector : public mixin {

      typedef std::shared_ptr<basic_vector> p;
      typedef typename node::base base_node;
      typedef leaf leaf_type;

      typedef Value value_type;

      uint64_t _cnt;
      uint64_t _shift;

      typename node::p _root;
      typename leaf::p _tail;

      inline basic_vector()
        : _cnt(0)
        , _shift(5)
        , _root(nu<node>())
        , _tail(nu<leaf>())
      {}

      template<typename T>
      inline basic_vector(const p& v, const T& val)
        : basic_vector(v, nu<value>(val))
      {}

      inline basic_vector(const p& v, const value::p& val)
        : _cnt(v->_cnt + 1)
        , _shift(v->_shift)
        , _tail(v->_tail)
      {
        if ((v->_cnt - v->tail_off()) < 32) {
          _shift = v->_shift;
          _root  = v->_root;
          _tail->_arr.push_back(val);
        }
        else {
          extend_root(v, val);
        }
      }

      template<typename T>
      static inline p from_std(const T& coll) {
        auto out = nu<basic_vector>();
        for (auto& val : coll) {
          out = nu<basic_vector>(out, val);
        }
        return out;
      }

      inline bool is_empty() const {
        return _cnt == 0;
      }

      inline uint64_t count() const {
        return _cnt;
      }

      inline const value_type& nth(uint64_t n) const {
        return *(*leaf_for(n))[n & 0x01f];
      }

      template<typename T>
      inline const T& nth(uint64_t n) const {
        return value_cast<T>(nth(n));
      }

      inline const value_type& operator[](uint64_t n) const {
        return nth(n);
      }

      inline const value_type& operator()(uint64_t n) const {
        return nth(n);
      }

      template<typename S>
      inline friend bool operator== (
        const p& self, const std::shared_ptr<S>& x) {

        return seqs::equiv(seq(self), x);
      }

      inline uint64_t tail_off() const {
        return (_cnt < 32) ? 0 : ((_cnt - 1) >> 5) << 5;
      }

      inline const typename leaf::p leaf_for(uint64_t n) const {
        if (n >= 0 && n < _cnt) {
          if (n >= tail_off()) {
            return _tail;
          }
          typename node::base out = _root;
          for (auto level = _shift; level > 0; level -= 5) {
            auto inner = std::dynamic_pointer_cast<node>(out);
            out = inner->_arr[(n >> level) & 0x01f];
          }
          return std::dynamic_pointer_cast<leaf>(out);
        }
        throw out_of_bounds(n, _cnt);
      }

      inline void extend_root(const basic_vector::p& v, const value::p& val) {

        auto new_leaf = nu<leaf>(v->_tail);
        _tail = nu<leaf>(val);

        bool overflow = ((v->_cnt >> 5) > (1 << v->_shift));
        if (overflow) {
          _shift = v->_shift + 5;
          _root  = nu<node>(v->_root, node::new_path(v->_shift, new_leaf));
        }
        else {
          _root = node::push_tail(v->_cnt, _shift, v->_root, new_leaf);
        }
      }
    };

    typedef basic_vector<> vector;

    template<typename V = vector, typename mixin = no_mixin>
    struct basic_chunked_seq {

      typedef std::shared_ptr<basic_chunked_seq> p;

      typedef typename V::value_type value_type;
      typedef typename V::leaf_type  leaf_type;

      mixin _mixin;

      vector::p _vec;
      uint64_t  _idx;
      uint64_t  _off;

      typename leaf_type::p _leaf;

      inline basic_chunked_seq(const vector::p& v, uint64_t i, uint64_t o)
        : _vec(v)
        , _idx(i)
        , _off(o)
        , _leaf(v->leaf_for(_idx))
      {}

      inline bool is_empty() const {
        return (_off >= _leaf->_arr.size());
      }

      template<typename T>
      inline const T& first() const {
        return value_cast<T>((*_leaf)[_off]);
      }

      inline const value_type& first() const {
        return *(*_leaf)[_off];
      };

      inline p rest() const {
        if (!is_empty()) {
          return nu<basic_chunked_seq>(_vec, _idx, _off + 1);
        }
        return p();
      }

      template<typename S>
      inline friend bool operator== (
        const p& self, const std::shared_ptr<S> x) {

        return seqs::equiv(self, x);
      }
    };

    typedef basic_chunked_seq<> chunked_seq;
  }

  inline ty::vector::p vector() {
    return nu<ty::vector>();
  }

  template<typename Arg>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x) {
    return conj(v, x);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x, Args... args) {
    return vector(conj(v, x), args...);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const Arg& x, Args... args) {
    return vector(vector(), x, args...);
  }

  template<typename T>
  inline auto vector(const T& coll)
    -> decltype(std::begin(coll), std::end(coll), ty::list::p()) {
    return ty::vector::from_std(coll);
  }

  template<typename T>
  inline ty::vector::p vector(std::initializer_list<T> l) {
    return ty::vector::from_std(l);
  }

  inline ty::vector::p vector(std::initializer_list<value> l) {
    return ty::vector::from_std(l);
  }

  // @cond HIDE
  template<typename... TS>
  inline ty::chunked_seq::p seq(
    const typename ty::basic_vector<TS...>::p& v) {

    typedef typename std::decay<decltype(*v)>::type V;
    typedef typename ty::basic_chunked_seq<V> seq;

    if (!v || v->is_empty()) {
      return typename seq::p();
    }
    return nu<seq>(v, 0, 0);
  }

  template<typename T, typename... TS>
  inline ty::vector::p conj(
    const typename ty::basic_vector<TS...>::p& v, const T& x) {

    return nu<ty::vector>(v, x);
  }
  // @endcond
}
<commit_msg>revert performance optimization for values. this needs some more work to properly detect types<commit_after>#pragma once

#include "seq.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>
#include <vector>

namespace imu {

  namespace ty {

    template<typename mixin = no_mixin>
    struct base_node {

      typedef std::shared_ptr<base_node> p;

      mixin _mixin;

      virtual ~base_node()
      {}
    };

    template<typename mixin = no_mixin>
    struct basic_node : public base_node<mixin> {

      typedef std::shared_ptr<basic_node> p;
      typedef typename base_node<mixin>::p base;

      std::vector<base> _arr;

      inline basic_node()
        : _arr(32)
      {}

      inline basic_node(const base& root, const base& node)
        : basic_node()
      {
        _arr[0] = root;
        _arr[1] = node;
      }

      inline basic_node(const base& child)
        : basic_node()
      {
        _arr[0] = child;
      }

      static inline base new_path(uint64_t level, const base& node) {

        base out(node);
        for(auto l = level; level != 0; level -= 5) {
          out = base(nu<basic_node>(out));
        }
        return out;
      }

      static inline p push_tail(
          uint64_t cnt
        , uint64_t level
        , const p& parent
        , const base& tail) {

        p out(nu<basic_node>(*parent));
        base insert;

        uint64_t idx = ((cnt - 1) >> level) & 0x01f;

        if (level == 5) {
          insert = tail;
        }
        else {
          auto child = parent->_arr[idx];
          if (child) {
            auto as_base = std::dynamic_pointer_cast<basic_node>(child);
            insert = push_tail(cnt, level - 5, as_base, tail);
          }
          else {
            insert = new_path(level - 5, tail);
          }
        }

        out->_arr[idx] = insert;

        return out;
      }
    };

    template<typename Value, typename mixin = no_mixin>
    struct basic_leaf : public base_node<mixin> {

      typedef std::shared_ptr<basic_leaf> p;
      typedef base_node<mixin> base;

      std::vector<Value> _arr;

      inline basic_leaf()
      {}

      inline basic_leaf(const basic_leaf::p& a)
        : _arr(a->_arr)
      {}

      inline basic_leaf(const Value& val)
      { _arr.push_back(val); }

      inline const Value& operator[](uint64_t n) const {
        return _arr[n];
      }
    };

    template<
        typename Value = value
      , typename mixin = no_mixin
      , typename node  = basic_node<>
      , typename leaf  = basic_leaf<Value>
      >
    struct basic_vector : public mixin {

      typedef std::shared_ptr<basic_vector> p;
      typedef typename node::base base_node;
      typedef leaf leaf_type;

      typedef Value value_type;

      uint64_t _cnt;
      uint64_t _shift;

      typename node::p _root;
      typename leaf::p _tail;

      inline basic_vector()
        : _cnt(0)
        , _shift(5)
        , _root(nu<node>())
        , _tail(nu<leaf>())
      {}

      template<typename T>
      inline basic_vector(const p& v, const T& val)
        : basic_vector(v, nu<value>(val))
      {}

      inline basic_vector(const p& v, const value::p& val)
        : _cnt(v->_cnt + 1)
        , _shift(v->_shift)
        , _tail(v->_tail)
      {
        if ((v->_cnt - v->tail_off()) < 32) {
          _shift = v->_shift;
          _root  = v->_root;
          _tail->_arr.push_back(val);
        }
        else {
          extend_root(v, val);
        }
      }

      template<typename T>
      static inline p from_std(const T& coll) {
        auto out = nu<basic_vector>();
        for (auto& val : coll) {
          out = nu<basic_vector>(out, val);
        }
        return out;
      }

      inline bool is_empty() const {
        return _cnt == 0;
      }

      inline uint64_t count() const {
        return _cnt;
      }

      inline const value_type& nth(uint64_t n) const {
        return (*leaf_for(n))[n & 0x01f];
      }

      template<typename T>
      inline const T& nth(uint64_t n) const {
        return value_cast<T>(nth(n));
      }

      inline const value_type& operator[](uint64_t n) const {
        return nth(n);
      }

      inline const value_type& operator()(uint64_t n) const {
        return nth(n);
      }

      template<typename S>
      inline friend bool operator== (
        const p& self, const std::shared_ptr<S>& x) {

        return seqs::equiv(seq(self), x);
      }

      inline uint64_t tail_off() const {
        return (_cnt < 32) ? 0 : ((_cnt - 1) >> 5) << 5;
      }

      inline const typename leaf::p leaf_for(uint64_t n) const {
        if (n >= 0 && n < _cnt) {
          if (n >= tail_off()) {
            return _tail;
          }
          typename node::base out = _root;
          for (auto level = _shift; level > 0; level -= 5) {
            auto inner = std::dynamic_pointer_cast<node>(out);
            out = inner->_arr[(n >> level) & 0x01f];
          }
          return std::dynamic_pointer_cast<leaf>(out);
        }
        throw out_of_bounds(n, _cnt);
      }

      inline void extend_root(const basic_vector::p& v, const value::p& val) {

        auto new_leaf = nu<leaf>(v->_tail);
        _tail = nu<leaf>(val);

        bool overflow = ((v->_cnt >> 5) > (1 << v->_shift));
        if (overflow) {
          _shift = v->_shift + 5;
          _root  = nu<node>(v->_root, node::new_path(v->_shift, new_leaf));
        }
        else {
          _root = node::push_tail(v->_cnt, _shift, v->_root, new_leaf);
        }
      }
    };

    typedef basic_vector<> vector;

    template<typename V = vector, typename mixin = no_mixin>
    struct basic_chunked_seq {

      typedef std::shared_ptr<basic_chunked_seq> p;

      typedef typename V::value_type value_type;
      typedef typename V::leaf_type  leaf_type;

      mixin _mixin;

      vector::p _vec;
      uint64_t  _idx;
      uint64_t  _off;

      typename leaf_type::p _leaf;

      inline basic_chunked_seq(const vector::p& v, uint64_t i, uint64_t o)
        : _vec(v)
        , _idx(i)
        , _off(o)
        , _leaf(v->leaf_for(_idx))
      {}

      inline bool is_empty() const {
        return (_off >= _leaf->_arr.size());
      }

      template<typename T>
      inline const T& first() const {
        return value_cast<T>((*_leaf)[_off]);
      }

      inline const value_type& first() const {
        return (*_leaf)[_off];
      };

      inline p rest() const {
        if (!is_empty()) {
          return nu<basic_chunked_seq>(_vec, _idx, _off + 1);
        }
        return p();
      }

      template<typename S>
      inline friend bool operator== (
        const p& self, const std::shared_ptr<S> x) {

        return seqs::equiv(self, x);
      }
    };

    typedef basic_chunked_seq<> chunked_seq;
  }

  inline ty::vector::p vector() {
    return nu<ty::vector>();
  }

  template<typename Arg>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x) {
    return conj(v, x);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x, Args... args) {
    return vector(conj(v, x), args...);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const Arg& x, Args... args) {
    return vector(vector(), x, args...);
  }

  template<typename T>
  inline auto vector(const T& coll)
    -> decltype(std::begin(coll), std::end(coll), ty::list::p()) {
    return ty::vector::from_std(coll);
  }

  template<typename T>
  inline ty::vector::p vector(std::initializer_list<T> l) {
    return ty::vector::from_std(l);
  }

  inline ty::vector::p vector(std::initializer_list<value> l) {
    return ty::vector::from_std(l);
  }

  // @cond HIDE
  template<typename... TS>
  inline ty::chunked_seq::p seq(
    const typename ty::basic_vector<TS...>::p& v) {

    typedef typename std::decay<decltype(*v)>::type V;
    typedef typename ty::basic_chunked_seq<V> seq;

    if (!v || v->is_empty()) {
      return typename seq::p();
    }
    return nu<seq>(v, 0, 0);
  }

  template<typename T, typename... TS>
  inline ty::vector::p conj(
    const typename ty::basic_vector<TS...>::p& v, const T& x) {

    return nu<ty::vector>(v, x);
  }
  // @endcond
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 Toshiro Yamada
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/// @file tnyosc-dispatch.hpp
/// @brief tnyosc dispatch header file
/// @author Toshiro Yamada
#ifndef __TNY_OSC_DISPATCH__
#define __TNY_OSC_DISPATCH__

#include <string>
#include <vector>
#include <list>
#include <tr1/memory>

#include <time.h>

namespace tnyosc {

struct Argument {
  char type;    // OSC type tag
  size_t size;  // size in byte
  union {
    int32_t i;  // int32
    float f;    // float32
    char* s;    // OSC-string
    void* b;    // OSC-blob
    int64_t h;  // int64
    double d;   // float64
    uint64_t t; // OSC-timetag
    char* S;    // Alternate OSC-string, such as "symbols"
    char c;     // ASCII character
    uint32_t r; // 32-bit RGBA color
    struct {
      uint8_t port;
      uint8_t status;
      uint8_t data1;
      uint8_t data2;
    } m;        // MIDI data
  } data;

  ~Argument() {
    switch(type) {
      case 's':
      case 'S':
        free(data.s);
        break;
      case'b':
        free(data.b);
        break;
    }
  }
};

typedef void (*osc_method)(const std::string& address,
    const std::vector<Argument>& argv, void* user_data);

// structure to hold method handles
struct MethodTemplate {
  std::string address; // OSC-Address
  std::string types; // OSC-types as a string
  void* user_data; // user data
  osc_method method; // OSC-Methods to call
};

struct ParsedMessage {
  struct timeval timetag;
  std::string address;
  std::string types;
  std::vector<Argument> argv;
};

// structure to hold callback function for a given OSC packet
struct Callback {
  struct timeval timetag; // OSC-timetag to determine when to call the method
  std::string address;
  std::vector<Argument> argv;
  void* user_data; // user data
  osc_method method; // matched method to call
};

typedef std::tr1::shared_ptr<Callback> CallbackRef;
// use to sort list<Callback> according to their timetag

class Dispatcher {
 public:
  Dispatcher();
  ~Dispatcher();

  /// Add a method template that may respond to an incoming Open Sound Control
  /// message. Use match_methods to deserialize a raw OSC message and match
  /// with the added methods.
  void add_method(const char* address, const char* types,
      osc_method method, void* user_data);

  /// Deserializes a raw Open Sound Control message (as coming from a network)
  /// and returns a list of CallbackRef that matches with the registered method
  /// tempaltes.
  std::list<CallbackRef> match_methods(const unsigned char* data, size_t size);

 private:
  static const struct timeval kZeroTimetag;

  bool decode_data(const unsigned char* data, size_t size,
      std::list<ParsedMessage>& messages, struct timeval timetag=kZeroTimetag);
  bool decode_osc(const unsigned char* data, size_t size,
      std::list<ParsedMessage>& messages, struct timeval timetag);
  bool pattern_match(const std::string& lhs, const std::string& rhs);

  std::list<MethodTemplate> methods_;
};

} // namespace tnyosc

#endif // __TNY_OSC_DISPATCH__

<commit_msg>Converting decode_data to public and static<commit_after>// Copyright (c) 2011 Toshiro Yamada
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/// @file tnyosc-dispatch.hpp
/// @brief tnyosc dispatch header file
/// @author Toshiro Yamada
#ifndef __TNY_OSC_DISPATCH__
#define __TNY_OSC_DISPATCH__

#include <string>
#include <vector>
#include <list>
#include <tr1/memory>

#include <time.h>

namespace tnyosc {

struct Argument {
  char type;    // OSC type tag
  size_t size;  // size in byte
  union {
    int32_t i;  // int32
    float f;    // float32
    char* s;    // OSC-string
    void* b;    // OSC-blob
    int64_t h;  // int64
    double d;   // float64
    uint64_t t; // OSC-timetag
    char* S;    // Alternate OSC-string, such as "symbols"
    char c;     // ASCII character
    uint32_t r; // 32-bit RGBA color
    struct {
      uint8_t port;
      uint8_t status;
      uint8_t data1;
      uint8_t data2;
    } m;        // MIDI data
  } data;

  ~Argument() {
    switch(type) {
      case 's':
      case 'S':
        free(data.s);
        break;
      case'b':
        free(data.b);
        break;
    }
  }
};

typedef void (*osc_method)(const std::string& address,
    const std::vector<Argument>& argv, void* user_data);

// structure to hold method handles
struct MethodTemplate {
  std::string address; // OSC-Address
  std::string types; // OSC-types as a string
  void* user_data; // user data
  osc_method method; // OSC-Methods to call
};

struct ParsedMessage {
  struct timeval timetag;
  std::string address;
  std::string types;
  std::vector<Argument> argv;
};

// structure to hold callback function for a given OSC packet
struct Callback {
  struct timeval timetag; // OSC-timetag to determine when to call the method
  std::string address;
  std::vector<Argument> argv;
  void* user_data; // user data
  osc_method method; // matched method to call
};

typedef std::tr1::shared_ptr<Callback> CallbackRef;
// use to sort list<Callback> according to their timetag

class Dispatcher {
 public:
  Dispatcher();
  ~Dispatcher();

  /// Add a method template that may respond to an incoming Open Sound Control
  /// message. Use match_methods to deserialize a raw OSC message and match
  /// with the added methods.
  void add_method(const char* address, const char* types,
      osc_method method, void* user_data);

  /// Deserializes a raw Open Sound Control message (as coming from a network)
  /// and returns a list of CallbackRef that matches with the registered method
  /// tempaltes.
  std::list<CallbackRef> match_methods(const unsigned char* data, size_t size);

  /// decode_data is called inside match_methods to extract the OSC data from
  /// a raw data.
  static bool decode_data(const unsigned char* data, size_t size,
      std::list<ParsedMessage>& messages, struct timeval timetag=kZeroTimetag);

 private:
  static const struct timeval kZeroTimetag;
  static bool decode_osc(const unsigned char* data, size_t size,
      std::list<ParsedMessage>& messages, struct timeval timetag);
  static bool pattern_match(const std::string& lhs, const std::string& rhs);

  std::list<MethodTemplate> methods_;
};

} // namespace tnyosc

#endif // __TNY_OSC_DISPATCH__

<|endoftext|>


<commit_before>/*
 * To compile this file with GCC, type:
 * g++ hello.cc -lboost_program_options -o hello
 */

#include <fstream>
#include <iostream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc, char ** argv) {

    /*
     * PARSE PROGRAM OPTIONS
     */

    /* *** Declare the supported options *** */

    po::options_description options_desc("Allowed options");
    options_desc.add_options()
        ("help", "produce help message")
        ("config", po::value<std::string>(), "set the config filename.")
        ("string_opt",  po::value<std::string>(), "a string option")
        ("integer_opt", po::value<int>(), "an integer option")
        ("double_opt",  po::value<double>(), "a float (double precision) option")
        ("boolean_opt", po::value<bool>(), "a boolean option")
    ;

    /* *** Parse commandline options *** */

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options_desc), vm);

    /* *** Parse config file *** */

    std::string config_filename;

    if(vm.count("config")) {
        config_filename = vm["config"].as<std::string>();
    }

    std::ifstream ifs(config_filename.c_str());
    po::store(po::parse_config_file(ifs, options_desc), vm);
    ifs.close();

    /* *** Notify *** */

    po::notify(vm);

    // Print help if required
    if(vm.count("help")) {
        std::cout << options_desc << std::endl;
        return 1;
    }

    /* *** Setup options *** */

    std::string string_var;
    int integer_var;
    double double_var;
    bool boolean_var;

    // Setup string_opt
    if(vm.count("string_opt")) {
        string_var = vm["string_opt"].as<std::string>();
        std::cout << "string option  = " << string_var << std::endl;
    }

    // Setup integer_opt
    if(vm.count("integer_opt")) {
        integer_var = vm["integer_opt"].as<int>();
        std::cout << "integer option = " << integer_var << std::endl;
    }

    // Setup double_opt
    if(vm.count("double_opt")) {
        double_var = vm["double_opt"].as<double>();
        std::cout << "double option  = " << double_var << std::endl;
    }

    // Setup boolean_opt
    if(vm.count("boolean_opt")) {
        boolean_var = vm["boolean_opt"].as<bool>();
        std::cout << "boolean option = " << boolean_var << std::endl;
    }

    /*
     * DO SOMETHING WITH PARSED OPTIONS...
     */

    // ...

}

<commit_msg>Add copyright notice.<commit_after>/*
 * Chrono: measure time duration between two points with boost.datetime
 *
 * Copyright (c) 2012 Jérémie Decock
 *
 * Required: boost.program_options library
 * Usage: g++ hello.cc -lboost_program_options -o hello
 *
 */

#include <fstream>
#include <iostream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc, char ** argv) {

    /*
     * PARSE PROGRAM OPTIONS
     */

    /* *** Declare the supported options *** */

    po::options_description options_desc("Allowed options");
    options_desc.add_options()
        ("help", "produce help message")
        ("config", po::value<std::string>(), "set the config filename.")
        ("string_opt",  po::value<std::string>(), "a string option")
        ("integer_opt", po::value<int>(), "an integer option")
        ("double_opt",  po::value<double>(), "a float (double precision) option")
        ("boolean_opt", po::value<bool>(), "a boolean option")
    ;

    /* *** Parse commandline options *** */

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options_desc), vm);

    /* *** Parse config file *** */

    std::string config_filename;

    if(vm.count("config")) {
        config_filename = vm["config"].as<std::string>();
    }

    std::ifstream ifs(config_filename.c_str());
    po::store(po::parse_config_file(ifs, options_desc), vm);
    ifs.close();

    /* *** Notify *** */

    po::notify(vm);

    // Print help if required
    if(vm.count("help")) {
        std::cout << options_desc << std::endl;
        return 1;
    }

    /* *** Setup options *** */

    std::string string_var;
    int integer_var;
    double double_var;
    bool boolean_var;

    // Setup string_opt
    if(vm.count("string_opt")) {
        string_var = vm["string_opt"].as<std::string>();
        std::cout << "string option  = " << string_var << std::endl;
    }

    // Setup integer_opt
    if(vm.count("integer_opt")) {
        integer_var = vm["integer_opt"].as<int>();
        std::cout << "integer option = " << integer_var << std::endl;
    }

    // Setup double_opt
    if(vm.count("double_opt")) {
        double_var = vm["double_opt"].as<double>();
        std::cout << "double option  = " << double_var << std::endl;
    }

    // Setup boolean_opt
    if(vm.count("boolean_opt")) {
        boolean_var = vm["boolean_opt"].as<bool>();
        std::cout << "boolean option = " << boolean_var << std::endl;
    }

    /*
     * DO SOMETHING WITH PARSED OPTIONS...
     */

    // ...

}

<|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*                Copyright 2004 by Ullrich Koethe                      */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_NAVIGATOR_HXX
#define VIGRA_NAVIGATOR_HXX

namespace vigra {

/********************************************************/
/*                                                      */
/*                MultiArrayNavigator                   */
/*                                                      */
/********************************************************/

/** \brief A navigator that provides acces to the 1D subranges of an
    n-dimensional range given by a \ref vigra::MultiIterator and an nD shape.

Normally, the innermost loop of an iteration extends over the innermost
dimension of a given array. Sometimes, however, it is necessary to have
some other dimension in the inner loop. For example, instead of iterating over
the rows, the inner loop should extend over the columns. The class MultiArrayNavigator
encapsulates the necessary functionality. Given an arbitrary dimensional
array (represented by a vigra::MultiIterator/shape pair), and the desired
inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible
starting points of 1D subsets along the given dimension (e.g. all columns). By calling
<TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compatible 1-dimensional
iterator for the current subset.

The template parameters specify the embedded iterator type and its dimension.

Usage:

\#include "vigra/navigator.hxx"

Namespace: vigra

\code
    typedef vigra::MultiArray<3, int>  Array;

    Array a(Array::difference_type(X, Y, Z));

    typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator;

    for(int d=0; d<3; ++d)
    {
        // create Navigator for dimension d
        Navigator nav(a.traverser_begin(), a.shape(), d);

        // outer loop: move navigator to all starting points
        // of 1D subsets that run parallel to coordinate axis d
        for(; nav.hasMore(); ++nav)
        {
            // inner loop: linear iteration over current subset
            //             d == {0, 1, 2}: interate along {x, y, z}-axis respectively
             Navigator::iterator i = nav.begin(), end = nav.end();
            for(; i != end; ++i)
                // do something
        }
    }
\endcode
*/
template <class MULTI_ITERATOR, unsigned int N>
class MultiArrayNavigator : public MultiArrayNavigator<MULTI_ITERATOR, N-1>
{
    typedef MultiArrayNavigator<MULTI_ITERATOR, N-1> base_type;

  public:
    enum { level = N-1 };

        /** The required shape type for the given iterator type.
         */
    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;

        /** The iterator type for the inner loop (result of begin() and end()).
         */
    typedef typename MULTI_ITERATOR::iterator iterator;

        /** Construct navigator for multi-dimensional iterator <TT>i</TT>, array shape <TT>shape</TT>
            and inner loop dimension <TT>inner_dimension</TT>.
         */
    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
    : base_type(i, shape, inner_dimension),
      i_(i),
      end_(i)
    {
        if(inner_dimension != level)
            end_.template dim<level>() += shape[level];
    }

        /** Advance to next starting location.
         */
    void operator++()
    {
        base_type::operator++();
        if(base_type::atEnd() && i_ < end_) // this tests implicitly inner_dimension_ != level
        {
            ++i_.template dim<level>();
            if(i_ < end_)
                base_type::reset(i_);
        }
    }

        /** Advance to next starting location.
         */
    void operator++(int)
    {
        ++*this;
    }

        /** true if there are more elements.
         */
    bool hasMore() const
    {
        return inner_dimension_ == level ?
                    base_type::hasMore() :
                    i_ < end_;
    }

        /** true if iterator is exhausted.
         */
    bool atEnd() const
    {
        return inner_dimension_ == level ?
                    base_type::atEnd() :
	            !( i_ < end_);
    }

  protected:
    void reset(MULTI_ITERATOR const & i)
    {
        end_ = i_ = i;
        if(inner_dimension_ != level)
            end_.template dim<level>() += shape_[level];
        base_type::reset(i);
    }

    MULTI_ITERATOR i_, end_;
};

template <class MULTI_ITERATOR>
class MultiArrayNavigator<MULTI_ITERATOR, 1>
{
  public:
    enum { level = 0 };
    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;
    typedef typename MULTI_ITERATOR::iterator iterator;

    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
    : shape_(shape),
      inner_dimension_(inner_dimension),
      i_(i),
      end_(i)
    {
        if(inner_dimension != level)
            end_.template dim<level>() += shape[level];
    }

    void operator++()
    {
        ++i_.template dim<level>();
    }

    void operator++(int)
    {
        ++*this;
    }

    iterator begin() const
    {
        return i_.iteratorForDimension(inner_dimension_);
    }

    iterator end() const
    {
        return begin() + shape_[inner_dimension_];
    }

    bool hasMore() const
    {
        return i_ < end_;
    }

    bool atEnd() const
    {
      return !( i_ < end_);
    }

  protected:
    void reset(MULTI_ITERATOR const & i)
    {
        end_ = i_ = i;
        if(inner_dimension_ != level)
            end_.template dim<level>() += shape_[level];
    }

    shape_type shape_;
    unsigned int inner_dimension_;
    MULTI_ITERATOR i_, end_;
};

} // namespace vigra

#endif /* VIGRA_NAVIGATOR_HXX */
<commit_msg>improved documentation<commit_after>/************************************************************************/
/*                                                                      */
/*                Copyright 2004 by Ullrich Koethe                      */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_NAVIGATOR_HXX
#define VIGRA_NAVIGATOR_HXX

namespace vigra {

/********************************************************/
/*                                                      */
/*                MultiArrayNavigator                   */
/*                                                      */
/********************************************************/

/** \brief A navigator that provides acces to the 1D subranges of an
    n-dimensional range given by a \ref vigra::MultiIterator and an nD shape.

    Normally, the innermost loop of an iteration extends over the innermost
    dimension of a given array. Sometimes, however, it is necessary to have
    some other dimension in the inner loop. For example, instead of iterating over
    the rows, the inner loop should extend over the columns. The class MultiArrayNavigator
    encapsulates the necessary functionality. Given an arbitrary dimensional
    array (represented by a vigra::MultiIterator/shape pair), and the desired
    inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible
    starting points of 1D subsets along the given dimension (e.g. all columns). By calling
    <TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compatible 1-dimensional
    iterator for the current subset.

    The template parameters specify the embedded iterator type and its dimension.

    Usage:

    \#include "vigra/navigator.hxx"

    Namespace: vigra

    \code
    typedef vigra::MultiArray<3, int>  Array;

    Array a(Array::size_type(X, Y, Z));

    typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator;

    for(int d=0; d<3; ++d)
    {
        // create Navigator for dimension d
        Navigator nav(a.traverser_begin(), a.shape(), d);

        // outer loop: move navigator to all starting points
        // of 1D subsets that run parallel to coordinate axis d
        for(; nav.hasMore(); ++nav)
        {
            // inner loop: linear iteration over current subset
            //             d == {0, 1, 2}: interate along {x, y, z}-axis respectively
             Navigator::iterator i = nav.begin(), end = nav.end();
            for(; i != end; ++i)
                // do something
        }
    }
    \endcode
*/
template <class MULTI_ITERATOR, unsigned int N>
class MultiArrayNavigator
: public MultiArrayNavigator<MULTI_ITERATOR, N-1>
{
    typedef MultiArrayNavigator<MULTI_ITERATOR, N-1> base_type;

  public:
    enum { level = N-1 };

        /** The required shape type for the given iterator type.
         */
    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;

        /** The iterator type for the inner loop (result of begin() and end()).
         */
    typedef typename MULTI_ITERATOR::iterator iterator;

        /** Construct navigator for multi-dimensional iterator <TT>i</TT>, array shape <TT>shape</TT>
            and inner loop dimension <TT>inner_dimension</TT>.
         */
    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
    : base_type(i, shape, inner_dimension),
      i_(i),
      end_(i)
    {
        if(inner_dimension != level)
            end_.template dim<level>() += shape[level];
    }

        /** Advance to next starting location.
         */
    void operator++()
    {
        base_type::operator++();
        if(base_type::atEnd() && i_ < end_) // this tests implicitly inner_dimension_ != level
        {
            ++i_.template dim<level>();
            if(i_ < end_)
                base_type::reset(i_);
        }
    }

        /** Advance to next starting location.
         */
    void operator++(int)
    {
        ++*this;
    }

        /** true if there are more elements.
         */
    bool hasMore() const
    {
        return inner_dimension_ == level ?
                    base_type::hasMore() :
                    i_ < end_;
    }

        /** true if iterator is exhausted.
         */
    bool atEnd() const
    {
        return inner_dimension_ == level ?
                    base_type::atEnd() :
	            !( i_ < end_);
    }

  protected:
    void reset(MULTI_ITERATOR const & i)
    {
        end_ = i_ = i;
        if(inner_dimension_ != level)
            end_.template dim<level>() += shape_[level];
        base_type::reset(i);
    }

    MULTI_ITERATOR i_, end_;
};

template <class MULTI_ITERATOR>
class MultiArrayNavigator<MULTI_ITERATOR, 1>
{
  public:
    enum { level = 0 };
    typedef typename MULTI_ITERATOR::multi_difference_type shape_type;
    typedef typename MULTI_ITERATOR::iterator iterator;

    MultiArrayNavigator(MULTI_ITERATOR const & i, shape_type const & shape, unsigned int inner_dimension)
    : shape_(shape),
      inner_dimension_(inner_dimension),
      i_(i),
      end_(i)
    {
        if(inner_dimension != level)
            end_.template dim<level>() += shape[level];
    }

    void operator++()
    {
        ++i_.template dim<level>();
    }

    void operator++(int)
    {
        ++*this;
    }

    iterator begin() const
    {
        return i_.iteratorForDimension(inner_dimension_);
    }

    iterator end() const
    {
        return begin() + shape_[inner_dimension_];
    }

    bool hasMore() const
    {
        return i_ < end_;
    }

    bool atEnd() const
    {
      return !( i_ < end_);
    }

  protected:
    void reset(MULTI_ITERATOR const & i)
    {
        end_ = i_ = i;
        if(inner_dimension_ != level)
            end_.template dim<level>() += shape_[level];
    }

    shape_type shape_;
    unsigned int inner_dimension_;
    MULTI_ITERATOR i_, end_;
};

} // namespace vigra

#endif /* VIGRA_NAVIGATOR_HXX */
<|endoftext|>


<commit_before>/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @aaram a, b, the root of binary trees.
     * @return true if they are identical, or false.
     */
    bool isIdentical(TreeNode* a, TreeNode* b) {
        // Write your code here
        bool rt_identical_flag=false;
        if ((a==NULL and b!=NULL) or (a!=NULL and b==NULL)) return false;
        if (a->val == b-> val) rt_identical_flag=true;
            else return false;

        rt_identical_flag = rt_identical_flag and isIdentical(a->left,b->left) and isIdentical(a->right,b->right);
        return rt_identical_flag;
    }
};<commit_msg>Add a condition<commit_after>/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @aaram a, b, the root of binary trees.
     * @return true if they are identical, or false.
     */
    bool isIdentical(TreeNode* a, TreeNode* b) {
        // Write your code here
        bool rt_identical_flag=false;
        // if ((a==NULL and b!=NULL) or (a!=NULL and b==NULL)) return false;
        if ((a==NULL and b==NULL) or (a->val == b-> val)) rt_identical_flag=true;
            else return false;

        rt_identical_flag = rt_identical_flag and isIdentical(a->left,b->left) and isIdentical(a->right,b->right);
        return rt_identical_flag;
    }
};<|endoftext|>


<commit_before>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ inlcludes

// Local includes
#include "fe.h"
#include "elem.h"

template <>
Real FE<0,LAGRANGE>::shape(const ElemType,
			   const Order,
			   const unsigned int i,
			   const Point&)
{
  libmesh_assert (i < 1);
  return 1.;
}

template <>
Real FE<0,LAGRANGE>::shape(const Elem*,
			   const Order,
			   const unsigned int i,
			   const Point&)
{
  libmesh_assert (i < 1);
  return 1.;
}

template <>
Real FE<0,LAGRANGE>::shape_deriv(const ElemType,
				 const Order,
				 const unsigned int,
				 const unsigned int,
				 const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_deriv(const Elem*,
				 const Order,
				 const unsigned int,
				 const unsigned int,
				 const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_second_deriv(const ElemType,
					const Order,
					const unsigned int,
					const unsigned int,
					const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_second_deriv(const Elem*,
				        const Order,
				        const unsigned int,
				        const unsigned int,
				        const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}
<commit_msg>comment typo fix<commit_after>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "fe.h"
#include "elem.h"

template <>
Real FE<0,LAGRANGE>::shape(const ElemType,
			   const Order,
			   const unsigned int i,
			   const Point&)
{
  libmesh_assert (i < 1);
  return 1.;
}

template <>
Real FE<0,LAGRANGE>::shape(const Elem*,
			   const Order,
			   const unsigned int i,
			   const Point&)
{
  libmesh_assert (i < 1);
  return 1.;
}

template <>
Real FE<0,LAGRANGE>::shape_deriv(const ElemType,
				 const Order,
				 const unsigned int,
				 const unsigned int,
				 const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_deriv(const Elem*,
				 const Order,
				 const unsigned int,
				 const unsigned int,
				 const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_second_deriv(const ElemType,
					const Order,
					const unsigned int,
					const unsigned int,
					const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}

template <>
Real FE<0,LAGRANGE>::shape_second_deriv(const Elem*,
				        const Order,
				        const unsigned int,
				        const unsigned int,
				        const Point&)
{
  // No spatial derivatives in 0D!
  libmesh_error();
  return 0.;
}
<|endoftext|>


<commit_before>/**
 * @file exoflickr
 * @brief Lightweight wrapper around the Flickr API for signing and such
 *
 * $LicenseInfo:firstyear=2012&license=viewerlgpl$
 * Copyright (C) 2012 Katharine Berry
 *
 * 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;
 * version 2.1 of the License only.
 *
 * 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.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llbufferstream.h"
#include "lluri.h"
#include "llhttpclient.h"
#include "llxmltree.h"
#include "llsdserialize.h"
#include "llviewercontrol.h"
#include "llbase64.h"

// third-party
#if LL_STANDALONE
#include "jsoncpp/reader.h" // JSON
#else
#include "reader.h" // JSON
#endif

#include <openssl/hmac.h>
#include <openssl/evp.h>

#include "exoflickr.h"

class exoFlickrResponse : public LLHTTPClient::Responder
{
public:
	exoFlickrResponse(exoFlickr::response_callback_t &callback);
	/* virtual */ void completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer);
private:
	exoFlickr::response_callback_t mCallback;
};

class exoFlickrUploadResponse : public LLHTTPClient::Responder
{
public:
	exoFlickrUploadResponse(exoFlickr::response_callback_t &callback);
	/* virtual */ void completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer);
private:
	exoFlickr::response_callback_t mCallback;
};

//static
void exoFlickr::request(const std::string& method, const LLSD& args, response_callback_t callback)
{
	LLSD params(args);
	params["format"] = "json";
	params["method"] = method;
	params["nojsoncallback"] = 1;
	signRequest(params, "GET", "http://api.flickr.com/services/rest/");
	LLHTTPClient::get("http://api.flickr.com/services/rest/", params, new exoFlickrResponse(callback));
}

void exoFlickr::signRequest(LLSD& params, std::string method, std::string url)
{
	// Oauth junk
	params["oauth_consumer_key"] = EXO_FLICKR_API_KEY;
	std::string oauth_token = gSavedPerAccountSettings.getString("ExodusFlickrToken");
	if(oauth_token.length())
	{
	   params["oauth_token"] = oauth_token;
	}
	params["oauth_signature_method"] = "HMAC-SHA1";
	params["oauth_timestamp"] = (LLSD::Integer)time(NULL);
	params["oauth_nonce"] = ll_rand();
	params["oauth_version"] = "1.0";
	params["oauth_signature"] = getSignatureForCall(params, url, method); // This must be the last one set.
}

//static
void exoFlickr::uploadPhoto(const LLSD& args, LLImageFormatted *image, response_callback_t callback)
{
	LLSD params(args);
	signRequest(params, "POST", "http://api.flickr.com/services/upload/");

	// It would be nice if there was an easy way to do multipart form data. Oh well.
	const std::string boundary = "------------abcdefgh012345";
	std::ostringstream post_stream;
	post_stream << "--" << boundary;
	// Add all the parameters from LLSD to the query.
	for(LLSD::map_const_iterator itr = params.beginMap(); itr != params.endMap(); ++itr)
	{
		post_stream << "\r\nContent-Disposition: form-data; name=\"" << itr->first << "\"";
		post_stream << "\r\n\r\n" << itr->second.asString();
		post_stream << "\r\n" << "--" << boundary;
	}
	// Headers for the photo
	post_stream << "\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"snapshot." << image->getExtension() << "\"";
	post_stream << "\r\nContent-Type: ";
	// Apparently LLImageFormatted doesn't know what mimetype it has.
	if(image->getExtension() == "jpg")
	{
		post_stream << "image/jpeg";
	}
	else if(image->getExtension() == "png")
	{
		post_stream << "image/png";
	}
	else // This will (probably) only happen if someone decides to put the BMP entry back in the format selection floater.
	{    // I wonder if Flickr would do the right thing.
		post_stream << "application/x-wtf";
		LL_WARNS("FlickrAPI") << "Uploading unknown image type." << LL_ENDL;
	}
	post_stream << "\r\n\r\n";

	// Now we build the postdata array, including the photo in the middle of it.
	std::string post_str = post_stream.str();
	size_t total_data_size = image->getDataSize() + post_str.length() + boundary.length() + 6; // + 6 = "\r\n" + "--" + "--"
	char* post_data = new char[total_data_size + 1];
	memcpy(post_data, post_str.data(), post_str.length());
	char* address = post_data + post_str.length();
	memcpy(address, image->getData(), image->getDataSize());
	address += image->getDataSize();
	std::string post_tail = "\r\n--" + boundary + "--";
	memcpy(address, post_tail.data(), post_tail.length());
	address += post_tail.length();
	llassert(address <= post_data + total_data_size /* After all that, check we didn't overrun */);

	// We have a post body! Now we can go about building the actual request...
	LLSD headers;
	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
	// <FS:TS> Patch from Exodus:
	// The default timeout (one minute) isn't enough for a large picture.
	// 10 minutes is arbitrary, but should be long enough.
	LLHTTPClient::postRaw("http://api.flickr.com/services/upload/", (U8*)post_data, total_data_size, new exoFlickrUploadResponse(callback), headers, 600);
	// </FS:TS>
	// The HTTP client takes ownership of our post_data array,
	// and will delete it when it's done.
}

//static
std::string exoFlickr::getSignatureForCall(const LLSD& parameters, std::string url, std::string method)
{
	std::vector<std::string> keys;
	for(LLSD::map_const_iterator itr = parameters.beginMap(); itr != parameters.endMap(); ++itr)
	{
		keys.push_back(itr->first);
	}
	std::sort(keys.begin(), keys.end());
	std::ostringstream q;
	q << LLURI::escape(method);
	q << "&" << LLURI::escape(url) << "&";
	for(std::vector<std::string>::const_iterator itr  = keys.begin(); itr != keys.end(); ++itr)
	{
		if(itr != keys.begin())
		{
			q << "%26";
		}
		q << LLURI::escape(*itr);
		q << "%3D" << LLURI::escape(LLURI::escape(parameters[*itr]));
	}

	unsigned char data[EVP_MAX_MD_SIZE];
	unsigned int length;
	std::string key = std::string(EXO_FLICKR_API_SECRET) + "&" + gSavedPerAccountSettings.getString("ExodusFlickrTokenSecret");

	std::string to_hash = q.str();
	HMAC(EVP_sha1(), (void*)key.c_str(), key.length(), (unsigned char*)to_hash.c_str(), to_hash.length(), data, &length);
	std::string signature = LLBase64::encode((U8*)data, length);
	return signature;
}

exoFlickrUploadResponse::exoFlickrUploadResponse(exoFlickr::response_callback_t &callback)
: mCallback(callback)
{
}

void exoFlickrUploadResponse::completedRaw(
										  U32 status,
										  const std::string& reason,
										  const LLChannelDescriptors& channels,
										  const LLIOPipe::buffer_ptr_t& buffer)
{
	LLBufferStream istr(channels, buffer.get());
	std::stringstream strstrm;
	strstrm << istr.rdbuf();
	std::string result = std::string(strstrm.str());

	LLSD output;
	bool success;

	LLXmlTree tree;
	if(!tree.parseString(result))
	{
		LL_WARNS("FlickrAPI") << "Couldn't parse flickr response(" << status << "): " << result << LL_ENDL;
		mCallback(false, LLSD());
		return;
	}
	LLXmlTreeNode* root = tree.getRoot();
	if(!root->hasName("rsp"))
	{
		LL_WARNS("FlickrAPI") << "Bad root node: " << root->getName() << LL_ENDL;
		mCallback(false, LLSD());
		return;
	}
	std::string stat;
	root->getAttributeString("stat", stat);
	output["stat"] = stat;
	if(stat == "ok")
	{
		success = true;
		LLXmlTreeNode* photoid_node = root->getChildByName("photoid");
		if(photoid_node)
		{
			output["photoid"] = photoid_node->getContents();
		}
	}
	else
	{
		success = false;
		LLXmlTreeNode* err_node = root->getChildByName("err");
		if(err_node)
		{
			S32 code;
			std::string msg;
			err_node->getAttributeS32("code", code);
			err_node->getAttributeString("msg", msg);
			output["code"] = code;
			output["msg"] = msg;
		}
	}
	mCallback(success, output);
}

static void JsonToLLSD(const Json::Value &root, LLSD &output)
{
	if(root.isObject())
	{
		Json::Value::Members keys = root.getMemberNames();
		for(Json::Value::Members::const_iterator itr = keys.begin(); itr != keys.end(); ++itr)
		{
			LLSD elem;
			JsonToLLSD(root[*itr], elem);
			output[*itr] = elem;
		}
	}
	else if(root.isArray())
	{
		for(Json::Value::const_iterator itr = root.begin(); itr != root.end(); ++itr)
		{
			LLSD elem;
			JsonToLLSD(*itr, elem);
			output.append(elem);
		}
	}
	else
	{
		switch(root.type())
		{
			case Json::intValue:
				output = root.asInt();
				break;
			case Json::realValue:
			case Json::uintValue:
				output = root.asDouble();
				break;
			case Json::stringValue:
				output = root.asString();
				break;
			case Json::booleanValue:
				output = root.asBool();
				break;
			case Json::nullValue:
				output = LLSD();
				break;
			default:
				break;
		}
	}
}

exoFlickrResponse::exoFlickrResponse(exoFlickr::response_callback_t &callback) :
mCallback(callback)
{
}

void exoFlickrResponse::completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer)
{
	LLBufferStream istr(channels, buffer.get());
	std::stringstream strstrm;
	strstrm << istr.rdbuf();
	std::string result = strstrm.str();
	Json::Value root;
	Json::Reader reader;

	bool success = reader.parse(result, root);
	if(!success)
	{
		mCallback(false, LLSD());
		return;
	}
	else
	{
		LL_INFOS("FlickrAPI") << "Got response string: " << result << LL_ENDL;
		LLSD response;
		JsonToLLSD(root, response);
		mCallback(isGoodStatus(status), response);
	}
}
<commit_msg>Change Flickr API URLs to https:// form. This may be obsoleted by SLShare2, but if that's not merged, it'll still work in the next release.<commit_after>/**
 * @file exoflickr
 * @brief Lightweight wrapper around the Flickr API for signing and such
 *
 * $LicenseInfo:firstyear=2012&license=viewerlgpl$
 * Copyright (C) 2012 Katharine Berry
 *
 * 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;
 * version 2.1 of the License only.
 *
 * 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.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llbufferstream.h"
#include "lluri.h"
#include "llhttpclient.h"
#include "llxmltree.h"
#include "llsdserialize.h"
#include "llviewercontrol.h"
#include "llbase64.h"

// third-party
#if LL_STANDALONE
#include "jsoncpp/reader.h" // JSON
#else
#include "reader.h" // JSON
#endif

#include <openssl/hmac.h>
#include <openssl/evp.h>

#include "exoflickr.h"

class exoFlickrResponse : public LLHTTPClient::Responder
{
public:
	exoFlickrResponse(exoFlickr::response_callback_t &callback);
	/* virtual */ void completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer);
private:
	exoFlickr::response_callback_t mCallback;
};

class exoFlickrUploadResponse : public LLHTTPClient::Responder
{
public:
	exoFlickrUploadResponse(exoFlickr::response_callback_t &callback);
	/* virtual */ void completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer);
private:
	exoFlickr::response_callback_t mCallback;
};

//static
void exoFlickr::request(const std::string& method, const LLSD& args, response_callback_t callback)
{
	LLSD params(args);
	params["format"] = "json";
	params["method"] = method;
	params["nojsoncallback"] = 1;
	signRequest(params, "GET", "https://api.flickr.com/services/rest/");
	LLHTTPClient::get("https://api.flickr.com/services/rest/", params, new exoFlickrResponse(callback));
}

void exoFlickr::signRequest(LLSD& params, std::string method, std::string url)
{
	// Oauth junk
	params["oauth_consumer_key"] = EXO_FLICKR_API_KEY;
	std::string oauth_token = gSavedPerAccountSettings.getString("ExodusFlickrToken");
	if(oauth_token.length())
	{
	   params["oauth_token"] = oauth_token;
	}
	params["oauth_signature_method"] = "HMAC-SHA1";
	params["oauth_timestamp"] = (LLSD::Integer)time(NULL);
	params["oauth_nonce"] = ll_rand();
	params["oauth_version"] = "1.0";
	params["oauth_signature"] = getSignatureForCall(params, url, method); // This must be the last one set.
}

//static
void exoFlickr::uploadPhoto(const LLSD& args, LLImageFormatted *image, response_callback_t callback)
{
	LLSD params(args);
	signRequest(params, "POST", "https://up.flickr.com/services/upload/");

	// It would be nice if there was an easy way to do multipart form data. Oh well.
	const std::string boundary = "------------abcdefgh012345";
	std::ostringstream post_stream;
	post_stream << "--" << boundary;
	// Add all the parameters from LLSD to the query.
	for(LLSD::map_const_iterator itr = params.beginMap(); itr != params.endMap(); ++itr)
	{
		post_stream << "\r\nContent-Disposition: form-data; name=\"" << itr->first << "\"";
		post_stream << "\r\n\r\n" << itr->second.asString();
		post_stream << "\r\n" << "--" << boundary;
	}
	// Headers for the photo
	post_stream << "\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"snapshot." << image->getExtension() << "\"";
	post_stream << "\r\nContent-Type: ";
	// Apparently LLImageFormatted doesn't know what mimetype it has.
	if(image->getExtension() == "jpg")
	{
		post_stream << "image/jpeg";
	}
	else if(image->getExtension() == "png")
	{
		post_stream << "image/png";
	}
	else // This will (probably) only happen if someone decides to put the BMP entry back in the format selection floater.
	{    // I wonder if Flickr would do the right thing.
		post_stream << "application/x-wtf";
		LL_WARNS("FlickrAPI") << "Uploading unknown image type." << LL_ENDL;
	}
	post_stream << "\r\n\r\n";

	// Now we build the postdata array, including the photo in the middle of it.
	std::string post_str = post_stream.str();
	size_t total_data_size = image->getDataSize() + post_str.length() + boundary.length() + 6; // + 6 = "\r\n" + "--" + "--"
	char* post_data = new char[total_data_size + 1];
	memcpy(post_data, post_str.data(), post_str.length());
	char* address = post_data + post_str.length();
	memcpy(address, image->getData(), image->getDataSize());
	address += image->getDataSize();
	std::string post_tail = "\r\n--" + boundary + "--";
	memcpy(address, post_tail.data(), post_tail.length());
	address += post_tail.length();
	llassert(address <= post_data + total_data_size /* After all that, check we didn't overrun */);

	// We have a post body! Now we can go about building the actual request...
	LLSD headers;
	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
	// <FS:TS> Patch from Exodus:
	// The default timeout (one minute) isn't enough for a large picture.
	// 10 minutes is arbitrary, but should be long enough.
	LLHTTPClient::postRaw("https://up.flickr.com/services/upload/", (U8*)post_data, total_data_size, new exoFlickrUploadResponse(callback), headers, 600);
	// </FS:TS>
	// The HTTP client takes ownership of our post_data array,
	// and will delete it when it's done.
}

//static
std::string exoFlickr::getSignatureForCall(const LLSD& parameters, std::string url, std::string method)
{
	std::vector<std::string> keys;
	for(LLSD::map_const_iterator itr = parameters.beginMap(); itr != parameters.endMap(); ++itr)
	{
		keys.push_back(itr->first);
	}
	std::sort(keys.begin(), keys.end());
	std::ostringstream q;
	q << LLURI::escape(method);
	q << "&" << LLURI::escape(url) << "&";
	for(std::vector<std::string>::const_iterator itr  = keys.begin(); itr != keys.end(); ++itr)
	{
		if(itr != keys.begin())
		{
			q << "%26";
		}
		q << LLURI::escape(*itr);
		q << "%3D" << LLURI::escape(LLURI::escape(parameters[*itr]));
	}

	unsigned char data[EVP_MAX_MD_SIZE];
	unsigned int length;
	std::string key = std::string(EXO_FLICKR_API_SECRET) + "&" + gSavedPerAccountSettings.getString("ExodusFlickrTokenSecret");

	std::string to_hash = q.str();
	HMAC(EVP_sha1(), (void*)key.c_str(), key.length(), (unsigned char*)to_hash.c_str(), to_hash.length(), data, &length);
	std::string signature = LLBase64::encode((U8*)data, length);
	return signature;
}

exoFlickrUploadResponse::exoFlickrUploadResponse(exoFlickr::response_callback_t &callback)
: mCallback(callback)
{
}

void exoFlickrUploadResponse::completedRaw(
										  U32 status,
										  const std::string& reason,
										  const LLChannelDescriptors& channels,
										  const LLIOPipe::buffer_ptr_t& buffer)
{
	LLBufferStream istr(channels, buffer.get());
	std::stringstream strstrm;
	strstrm << istr.rdbuf();
	std::string result = std::string(strstrm.str());

	LLSD output;
	bool success;

	LLXmlTree tree;
	if(!tree.parseString(result))
	{
		LL_WARNS("FlickrAPI") << "Couldn't parse flickr response(" << status << "): " << result << LL_ENDL;
		mCallback(false, LLSD());
		return;
	}
	LLXmlTreeNode* root = tree.getRoot();
	if(!root->hasName("rsp"))
	{
		LL_WARNS("FlickrAPI") << "Bad root node: " << root->getName() << LL_ENDL;
		mCallback(false, LLSD());
		return;
	}
	std::string stat;
	root->getAttributeString("stat", stat);
	output["stat"] = stat;
	if(stat == "ok")
	{
		success = true;
		LLXmlTreeNode* photoid_node = root->getChildByName("photoid");
		if(photoid_node)
		{
			output["photoid"] = photoid_node->getContents();
		}
	}
	else
	{
		success = false;
		LLXmlTreeNode* err_node = root->getChildByName("err");
		if(err_node)
		{
			S32 code;
			std::string msg;
			err_node->getAttributeS32("code", code);
			err_node->getAttributeString("msg", msg);
			output["code"] = code;
			output["msg"] = msg;
		}
	}
	mCallback(success, output);
}

static void JsonToLLSD(const Json::Value &root, LLSD &output)
{
	if(root.isObject())
	{
		Json::Value::Members keys = root.getMemberNames();
		for(Json::Value::Members::const_iterator itr = keys.begin(); itr != keys.end(); ++itr)
		{
			LLSD elem;
			JsonToLLSD(root[*itr], elem);
			output[*itr] = elem;
		}
	}
	else if(root.isArray())
	{
		for(Json::Value::const_iterator itr = root.begin(); itr != root.end(); ++itr)
		{
			LLSD elem;
			JsonToLLSD(*itr, elem);
			output.append(elem);
		}
	}
	else
	{
		switch(root.type())
		{
			case Json::intValue:
				output = root.asInt();
				break;
			case Json::realValue:
			case Json::uintValue:
				output = root.asDouble();
				break;
			case Json::stringValue:
				output = root.asString();
				break;
			case Json::booleanValue:
				output = root.asBool();
				break;
			case Json::nullValue:
				output = LLSD();
				break;
			default:
				break;
		}
	}
}

exoFlickrResponse::exoFlickrResponse(exoFlickr::response_callback_t &callback) :
mCallback(callback)
{
}

void exoFlickrResponse::completedRaw(
									U32 status,
									const std::string& reason,
									const LLChannelDescriptors& channels,
									const LLIOPipe::buffer_ptr_t& buffer)
{
	LLBufferStream istr(channels, buffer.get());
	std::stringstream strstrm;
	strstrm << istr.rdbuf();
	std::string result = strstrm.str();
	Json::Value root;
	Json::Reader reader;

	bool success = reader.parse(result, root);
	if(!success)
	{
		mCallback(false, LLSD());
		return;
	}
	else
	{
		LL_INFOS("FlickrAPI") << "Got response string: " << result << LL_ENDL;
		LLSD response;
		JsonToLLSD(root, response);
		mCallback(isGoodStatus(status), response);
	}
}
<|endoftext|>


<commit_before><commit_msg>now drop not available yet includes<commit_after><|endoftext|>


<commit_before><commit_msg>do not change configured runtime system locale when setting UI locale<commit_after><|endoftext|>


<commit_before>/* DHT library

MIT license
written by Adafruit Industries
*/

#include "DHT.h"

DHT::DHT(uint8_t pin, uint8_t type) {
  _pin = pin;
  _type = type;
  firstreading = true;
}

void DHT::begin(void) {
  // set up the pins!
  pinMode(_pin, INPUT);
  digitalWrite(_pin, HIGH);
  _lastreadtime = 0;
}

float DHT::readTemperature(void) {
  float f;

  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[2];
      return f;
    case DHT22:
    case DHT21:
      f = data[2] & 0x7F;
      f *= 256;
      f += data[3];
      f /= 10;
      if (data[2] & 0x80)
	f *= -1;

      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}

float DHT::readHumidity(void) {
  float f;
  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[0];
      return f;
    case DHT22:
    case DHT21:
      f = data[0];
      f *= 256;
      f += data[1];
      f /= 10;
      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}

boolean DHT::read(void) {
  uint8_t laststate = HIGH;
  uint8_t counter = 0;
  uint8_t j = 0, i;
  unsigned long currenttime;

  // pull the pin high and wait 250 milliseconds
  digitalWrite(_pin, HIGH);
  delay(250);

  currenttime = millis();
  if (currenttime < _lastreadtime) {
    // ie there was a rollover
    _lastreadtime = 0;
  }
  if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
    return true; // return last correct measurement
    //delay(2000 - (currenttime - _lastreadtime));
  }
  firstreading = false;
  /*
    Serial.print("Currtime: "); Serial.print(currenttime);
    Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
  */
  _lastreadtime = millis();

  data[0] = data[1] = data[2] = data[3] = data[4] = 0;

  // now pull it low for ~20 milliseconds
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delay(20);
  cli();
  digitalWrite(_pin, HIGH);
  delayMicroseconds(40);
  pinMode(_pin, INPUT);

  // read in timings
  for ( i=0; i< MAXTIMINGS; i++) {
    counter = 0;
    while (digitalRead(_pin) == laststate) {
      counter++;
      delayMicroseconds(1);
      if (counter == 255) {
        break;
      }
    }
    laststate = digitalRead(_pin);

    if (counter == 255) break;

    // ignore first 3 transitions
    if ((i >= 4) && (i%2 == 0)) {
      // shove each bit into the storage bytes
      data[j/8] <<= 1;
      if (counter > 6)
        data[j/8] |= 1;
      j++;
    }

  }

  sei();

  /*
  Serial.println(j, DEC);
  Serial.print(data[0], HEX); Serial.print(", ");
  Serial.print(data[1], HEX); Serial.print(", ");
  Serial.print(data[2], HEX); Serial.print(", ");
  Serial.print(data[3], HEX); Serial.print(", ");
  Serial.print(data[4], HEX); Serial.print(" =? ");
  Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
  */

  // check we read 40 bits and that the checksum matches
  if ((j >= 40) &&
      (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
    return true;
  }

  return false;

}
<commit_msg>Added option for converting to Fahrenheit<commit_after>/* DHT library

MIT license
written by Adafruit Industries
*/

#include "DHT.h"

DHT::DHT(uint8_t pin, uint8_t type) {
  _pin = pin;
  _type = type;
  firstreading = true;
}

void DHT::begin(void) {
  // set up the pins!
  pinMode(_pin, INPUT);
  digitalWrite(_pin, HIGH);
  _lastreadtime = 0;
}

//boolean S == Scale.  True == Farenheit; False == Celcius
float DHT::readTemperature(bool S) {
  float f;

  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[2];
      if(S)
      	f = convertCtoF(f);

      return f;
    case DHT22:
    case DHT21:
      f = data[2] & 0x7F;
      f *= 256;
      f += data[3];
      f /= 10;
      if (data[2] & 0x80)
	f *= -1;
      if(S)
	f = convertCtoF(f);

      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}

float DHT::convertCtoF(float c) {
	return c * 9 / 5 + 32;
}

float DHT::readHumidity(void) {
  float f;
  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[0];
      return f;
    case DHT22:
    case DHT21:
      f = data[0];
      f *= 256;
      f += data[1];
      f /= 10;
      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}

boolean DHT::read(void) {
  uint8_t laststate = HIGH;
  uint8_t counter = 0;
  uint8_t j = 0, i;
  unsigned long currenttime;

  // pull the pin high and wait 250 milliseconds
  digitalWrite(_pin, HIGH);
  delay(250);

  currenttime = millis();
  if (currenttime < _lastreadtime) {
    // ie there was a rollover
    _lastreadtime = 0;
  }
  if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
    return true; // return last correct measurement
    //delay(2000 - (currenttime - _lastreadtime));
  }
  firstreading = false;
  /*
    Serial.print("Currtime: "); Serial.print(currenttime);
    Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
  */
  _lastreadtime = millis();

  data[0] = data[1] = data[2] = data[3] = data[4] = 0;

  // now pull it low for ~20 milliseconds
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delay(20);
  cli();
  digitalWrite(_pin, HIGH);
  delayMicroseconds(40);
  pinMode(_pin, INPUT);

  // read in timings
  for ( i=0; i< MAXTIMINGS; i++) {
    counter = 0;
    while (digitalRead(_pin) == laststate) {
      counter++;
      delayMicroseconds(1);
      if (counter == 255) {
        break;
      }
    }
    laststate = digitalRead(_pin);

    if (counter == 255) break;

    // ignore first 3 transitions
    if ((i >= 4) && (i%2 == 0)) {
      // shove each bit into the storage bytes
      data[j/8] <<= 1;
      if (counter > 6)
        data[j/8] |= 1;
      j++;
    }

  }

  sei();

  /*
  Serial.println(j, DEC);
  Serial.print(data[0], HEX); Serial.print(", ");
  Serial.print(data[1], HEX); Serial.print(", ");
  Serial.print(data[2], HEX); Serial.print(", ");
  Serial.print(data[3], HEX); Serial.print(", ");
  Serial.print(data[4], HEX); Serial.print(" =? ");
  Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
  */

  // check we read 40 bits and that the checksum matches
  if ((j >= 40) &&
      (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
    return true;
  }

  return false;

}
<|endoftext|>


<commit_before>#include "Log.h"
#include <iostream>
#include <Windows.h>
#include <fstream>
#include "common\ServerLogicManager.h"
using namespace std;
void Log::Debug(char * title, char * format, ...)
{
	va_list argp;
	va_start(argp, format);
	char str[1024];
	dealchars(str,format, argp);
	if (strcmp(str,"\0") == 0)
	{
		return;
	}

	std::string s = c_out(title, str);

	write(s);

}

void Log::Error(char * title, char * format, ...)
{
	va_list argp;
	va_start(argp, format);
	char str[1024];
	dealchars(str, format, argp);
	if (strcmp(str, "\0") == 0)
	{
		return;
	}

	std::string s = c_out(title, str,true);

	write(s);
}

char * Log::dealchars(char* str,char * format, va_list _ArgList)
{

//	auto i = _vscprintf(format, _ArgList);

	if (vsprintf(str, format, _ArgList) <= 0)
	{
		memset(str, 0, sizeof(str));
		return nullptr;
	}

	return str;
}

void Log::write(std::string str)
{
	static int i = 1;
	char buf[30];
	sprintf(buf, "log-[%s].log", sLM.getStringDataTime().c_str());
	fstream w;
	if (i == 1)
	{
		w.open(buf,  ofstream::out | ofstream::binary);
		--i;
	}
	else
	{
		w.open(buf, ofstream::app  | ofstream::binary);
	}

	if (!w.good())
	{
		w.close();
		return;
	}
	w << str;
	w.close();
}

std::string Log::c_out(char * title, char * format, bool isError)
{
	char buf[10];
	time_t ti = (time_t)time(0);
	tm localTime = *localtime(&ti);;
	strftime(buf, sizeof buf, "%R", &localTime);
	std::string str(buf);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY );
	cout << str << " ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	str += " ";
	if (isError)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |FOREGROUND_RED);
		cout << "E ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		str += "E ";
	}
	else
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
		cout << "D ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		str += "D ";
	}
	cout << "[Log] ";
	str += "[Log] ";

	cout << title;
	str += title;

	cout << ": ";
	str += ": ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
	cout << format;
	str += format;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	cout << '\n';
	str += '\n';
	return str;
}
<commit_msg>2016-6-17 17:50<commit_after>#include "Log.h"
#include <iostream>
#include <Windows.h>
#include <fstream>
#include "common\ServerLogicManager.h"
using namespace std;
void Log::Debug(char * title, char * format, ...)
{
	va_list argp;
	va_start(argp, format);
	char str[1024];
	dealchars(str,format, argp);
	if (strcmp(str,"\0") == 0)
	{
		return;
	}

	std::string s = c_out(title, str);

	write(s);

}

void Log::Error(char * title, char * format, ...)
{
	va_list argp;
	va_start(argp, format);
	char str[1024];
	dealchars(str, format, argp);
	if (strcmp(str, "\0") == 0)
	{
		return;
	}
	SERVER_LOG_INNER_LOCK
	std::string s = c_out(title, str,true);

	write(s);
}

char * Log::dealchars(char* str,char * format, va_list _ArgList)
{

//	auto i = _vscprintf(format, _ArgList);

	if (vsprintf(str, format, _ArgList) <= 0)
	{
		memset(str, 0, sizeof(str));
		return nullptr;
	}

	return str;
}

void Log::write(std::string str)
{
	static int i = 1;
	char buf[30];
	sprintf(buf, "log-[%s].log", sLM.getStringDataTime().c_str());
	fstream w;
	if (i == 1)
	{
		w.open(buf,  ofstream::out | ofstream::binary);
		--i;
	}
	else
	{
		w.open(buf, ofstream::app  | ofstream::binary);
	}

	if (!w.good())
	{
		w.close();
		return;
	}
	w << str;
	w.close();
}

std::string Log::c_out(char * title, char * format, bool isError)
{
	char buf[10];
	time_t ti = (time_t)time(0);
	tm localTime = *localtime(&ti);;
	strftime(buf, sizeof buf, "%R", &localTime);
	std::string str(buf);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY );
	cout << str << " ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	str += " ";
	if (isError)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |FOREGROUND_RED);
		cout << "E ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		str += "E ";
	}
	else
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
		cout << "D ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		str += "D ";
	}
	cout << "[Log] ";
	str += "[Log] ";

	cout << title;
	str += title;

	cout << ": ";
	str += ": ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
	cout << format;
	str += format;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY |
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	cout << '\n';
	str += '\n';
	return str;
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2018 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/Math/BasicPlotterDialog.h>
#include <Interface/Modules/Math/PlotDialog.h>
#include <Modules/Math/BasicPlotter.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
#include <QtGui>

#ifndef Q_MOC_RUN
#include <Core/Utils/StringUtil.h>
#endif

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Math;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Math;
using namespace SCIRun::Core::Datatypes;

BasicPlotterDialog::BasicPlotterDialog(const std::string& name, ModuleStateHandle state,
	QWidget* parent/* = 0*/)
	: ModuleDialogGeneric(state, parent), dataColors_(labelColorMax_), dataLabels_(labelColorMax_)
{
	setupUi(this);
	setWindowTitle(QString::fromStdString(name));
	fixSize();

	addDoubleSpinBoxManager(verticalAxisSpinBox_, Parameters::VerticalAxisPosition);
  addDoubleSpinBoxManager(horizontalAxisSpinBox_, Parameters::HorizontalAxisPosition);
	//addCheckBoxManager(verticalAxisGroupBox_, Parameters::VerticalAxisVisible);
  //addCheckBoxManager(horizontalAxisGroupBox_, Parameters::HorizontalAxisVisible);
	addLineEditManager(titleLineEdit_, Parameters::PlotTitle);
	addLineEditManager(xAxisLineEdit_, Parameters::XAxisLabel);
	addLineEditManager(yAxisLineEdit_, Parameters::YAxisLabel);
	addCheckBoxManager(showPointsCheckBox_, Parameters::ShowPointSymbols);
	addComboBoxManager(curveStyleComboBox_, Parameters::CurveStyle);
	connect(curveStyleComboBox_, SIGNAL(activated(const QString&)), this, SLOT(setCurveStyle(const QString&)));

	connect(showPlotPushButton_, SIGNAL(clicked()), this, SLOT(showPlot()));
	connect(exportPlotPushButton_, SIGNAL(clicked()), this, SLOT(exportPlot()));
	connect(dataColorPushButton_, SIGNAL(clicked()), this, SLOT(assignDataColor()));
  connect(backgroundColorPushButton_, SIGNAL(clicked()), this, SLOT(assignBackgroundColor()));
  connect(dataSeriesComboBox_, SIGNAL(activated(int)), this, SLOT(switchDataSeries(int)));
  connect(dataLineEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(assignDataLabel(const QString&)));
  dataSeriesComboBox_->setDisabled(true);

  plotDialog_ = new PlotDialog(this);
}

BasicPlotterDialog::~BasicPlotterDialog()
{
	delete plotDialog_;
}

void BasicPlotterDialog::pullSpecial()
{
  dataColors_ = colorsFromState(Parameters::PlotColors);
  dataColors_.resize(labelColorMax_);
  dataLabels_ = state_->getValue(Parameters::DataTitle).toVector();
  dataLabels_.resize(labelColorMax_);
  {
    ScopedWidgetSignalBlocker q(dataLineEdit_);
    dataLineEdit_->setText(QString::fromStdString(dataLabels_[dataSeriesIndex_].toString()));
  }
  backgroundColor_ = colorFromState(Parameters::PlotBackgroundColor);
  plotDialog_->plot()->setCanvasBackground(backgroundColor_);

	if (plotDialog_ && plotDialog_->isVisible())
		updatePlot();
}

void BasicPlotterDialog::showPlot()
{
	updatePlot();
	plotDialog_->show();
	plotDialog_->raise();
}

void BasicPlotterDialog::updatePlot()
{
  plotData();

  plotDialog_->updatePlot(titleLineEdit_->text(), xAxisLineEdit_->text(), yAxisLineEdit_->text(),
    boost::make_optional(horizontalAxisGroupBox_->isChecked(), horizontalAxisSpinBox_->value()),
    boost::make_optional(verticalAxisGroupBox_->isChecked(), verticalAxisSpinBox_->value()));
}

void BasicPlotterDialog::plotData()
{
  auto showPoints = showPointsCheckBox_->isChecked();
  auto data = transient_value_cast<DenseMatrixHandle>(state_->getTransientValue(Variables::InputMatrix));
	if (data)
	{
    auto plot = plotDialog_->plot();
		plot->clearCurves();
		plot->addCurve(data, dataLineEdit_->text(), dataColors_[dataSeriesIndex_], true, showPoints);
		plot->addLegend();
	}
}

void BasicPlotterDialog::assignDataColor()
{
  auto newColor = QColorDialog::getColor(dataColors_[dataSeriesIndex_], this, "Choose data color");
  if (newColor.isValid())
  {
		dataColors_[dataSeriesIndex_] = newColor;
    colorsToState(Parameters::PlotColors, dataColors_);
		updatePlot();
  }
}

void BasicPlotterDialog::assignBackgroundColor()
{
  auto newColor = QColorDialog::getColor(backgroundColor_, this, "Choose background color");
  if (newColor.isValid())
  {
		backgroundColor_ = newColor;
    colorToState(Parameters::PlotBackgroundColor, backgroundColor_);
    plotDialog_->plot()->setCanvasBackground(backgroundColor_);
  }
}

void BasicPlotterDialog::assignDataLabel(const QString& label)
{
  dataLabels_[dataSeriesIndex_].setValue(label.toStdString());
  state_->setValue(Parameters::DataTitle, dataLabels_);
  updatePlot();
}

void BasicPlotterDialog::exportPlot()
{
  plotDialog_->plot()->exportPlot();
}

void BasicPlotterDialog::switchDataSeries(int index)
{
  dataSeriesIndex_ = index;
  {
    ScopedWidgetSignalBlocker q(dataLineEdit_);
    dataLineEdit_->setText(QString::fromStdString(dataLabels_[dataSeriesIndex_].toString()));
  }
}

void BasicPlotterDialog::setCurveStyle(const QString& style)
{
	plotDialog_->plot()->setCurveStyle(style);
}

void BasicPlotterDialog::updateFromPortChange(int, const std::string&, DynamicPortChange type)
{
  if (type == DynamicPortChange::INITIAL_PORT_CONSTRUCTION)
    return;

	if (type == DynamicPortChange::USER_REMOVED_PORT)
	{
		state_->setTransientValue(Variables::InputMatrix, nullptr);
		plotDialog_->plot()->clearCurves();
		QMessageBox::warning(this, "Warning: Curves and plot data cleared", "Curves and plot data cleared. Re-execute to replot connected data.");
	}
}
<commit_msg>Convert messagebox to console warning<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2018 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/Math/BasicPlotterDialog.h>
#include <Interface/Modules/Math/PlotDialog.h>
#include <Modules/Math/BasicPlotter.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Logging/Log.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
#include <QtGui>

#ifndef Q_MOC_RUN
#include <Core/Utils/StringUtil.h>
#endif

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Math;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Algorithms::Math;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Logging;

BasicPlotterDialog::BasicPlotterDialog(const std::string& name, ModuleStateHandle state,
	QWidget* parent/* = 0*/)
	: ModuleDialogGeneric(state, parent), dataColors_(labelColorMax_), dataLabels_(labelColorMax_)
{
	setupUi(this);
	setWindowTitle(QString::fromStdString(name));
	fixSize();

	addDoubleSpinBoxManager(verticalAxisSpinBox_, Parameters::VerticalAxisPosition);
  addDoubleSpinBoxManager(horizontalAxisSpinBox_, Parameters::HorizontalAxisPosition);
	//addCheckBoxManager(verticalAxisGroupBox_, Parameters::VerticalAxisVisible);
  //addCheckBoxManager(horizontalAxisGroupBox_, Parameters::HorizontalAxisVisible);
	addLineEditManager(titleLineEdit_, Parameters::PlotTitle);
	addLineEditManager(xAxisLineEdit_, Parameters::XAxisLabel);
	addLineEditManager(yAxisLineEdit_, Parameters::YAxisLabel);
	addCheckBoxManager(showPointsCheckBox_, Parameters::ShowPointSymbols);
	addComboBoxManager(curveStyleComboBox_, Parameters::CurveStyle);
	connect(curveStyleComboBox_, SIGNAL(activated(const QString&)), this, SLOT(setCurveStyle(const QString&)));

	connect(showPlotPushButton_, SIGNAL(clicked()), this, SLOT(showPlot()));
	connect(exportPlotPushButton_, SIGNAL(clicked()), this, SLOT(exportPlot()));
	connect(dataColorPushButton_, SIGNAL(clicked()), this, SLOT(assignDataColor()));
  connect(backgroundColorPushButton_, SIGNAL(clicked()), this, SLOT(assignBackgroundColor()));
  connect(dataSeriesComboBox_, SIGNAL(activated(int)), this, SLOT(switchDataSeries(int)));
  connect(dataLineEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(assignDataLabel(const QString&)));
  dataSeriesComboBox_->setDisabled(true);

  plotDialog_ = new PlotDialog(this);
}

BasicPlotterDialog::~BasicPlotterDialog()
{
	delete plotDialog_;
}

void BasicPlotterDialog::pullSpecial()
{
  dataColors_ = colorsFromState(Parameters::PlotColors);
  dataColors_.resize(labelColorMax_);
  dataLabels_ = state_->getValue(Parameters::DataTitle).toVector();
  dataLabels_.resize(labelColorMax_);
  {
    ScopedWidgetSignalBlocker q(dataLineEdit_);
    dataLineEdit_->setText(QString::fromStdString(dataLabels_[dataSeriesIndex_].toString()));
  }
  backgroundColor_ = colorFromState(Parameters::PlotBackgroundColor);
  plotDialog_->plot()->setCanvasBackground(backgroundColor_);

	if (plotDialog_ && plotDialog_->isVisible())
		updatePlot();
}

void BasicPlotterDialog::showPlot()
{
	updatePlot();
	plotDialog_->show();
	plotDialog_->raise();
}

void BasicPlotterDialog::updatePlot()
{
  plotData();

  plotDialog_->updatePlot(titleLineEdit_->text(), xAxisLineEdit_->text(), yAxisLineEdit_->text(),
    boost::make_optional(horizontalAxisGroupBox_->isChecked(), horizontalAxisSpinBox_->value()),
    boost::make_optional(verticalAxisGroupBox_->isChecked(), verticalAxisSpinBox_->value()));
}

void BasicPlotterDialog::plotData()
{
  auto showPoints = showPointsCheckBox_->isChecked();
  auto data = transient_value_cast<DenseMatrixHandle>(state_->getTransientValue(Variables::InputMatrix));
	if (data)
	{
    auto plot = plotDialog_->plot();
		plot->clearCurves();
		plot->addCurve(data, dataLineEdit_->text(), dataColors_[dataSeriesIndex_], true, showPoints);
		plot->addLegend();
	}
}

void BasicPlotterDialog::assignDataColor()
{
  auto newColor = QColorDialog::getColor(dataColors_[dataSeriesIndex_], this, "Choose data color");
  if (newColor.isValid())
  {
		dataColors_[dataSeriesIndex_] = newColor;
    colorsToState(Parameters::PlotColors, dataColors_);
		updatePlot();
  }
}

void BasicPlotterDialog::assignBackgroundColor()
{
  auto newColor = QColorDialog::getColor(backgroundColor_, this, "Choose background color");
  if (newColor.isValid())
  {
		backgroundColor_ = newColor;
    colorToState(Parameters::PlotBackgroundColor, backgroundColor_);
    plotDialog_->plot()->setCanvasBackground(backgroundColor_);
  }
}

void BasicPlotterDialog::assignDataLabel(const QString& label)
{
  dataLabels_[dataSeriesIndex_].setValue(label.toStdString());
  state_->setValue(Parameters::DataTitle, dataLabels_);
  updatePlot();
}

void BasicPlotterDialog::exportPlot()
{
  plotDialog_->plot()->exportPlot();
}

void BasicPlotterDialog::switchDataSeries(int index)
{
  dataSeriesIndex_ = index;
  {
    ScopedWidgetSignalBlocker q(dataLineEdit_);
    dataLineEdit_->setText(QString::fromStdString(dataLabels_[dataSeriesIndex_].toString()));
  }
}

void BasicPlotterDialog::setCurveStyle(const QString& style)
{
	plotDialog_->plot()->setCurveStyle(style);
}

void BasicPlotterDialog::updateFromPortChange(int, const std::string&, DynamicPortChange type)
{
  if (type == DynamicPortChange::INITIAL_PORT_CONSTRUCTION)
    return;

	if (type == DynamicPortChange::USER_REMOVED_PORT)
	{
		state_->setTransientValue(Variables::InputMatrix, nullptr);
		plotDialog_->plot()->clearCurves();
		ModuleLog::Instance().get()->warn("[{}] Curves and plot data cleared. Re-execute to replot connected data.", windowTitle().toStdString());
	}
}
<|endoftext|>