<commit_before>// MIT License

// Copyright (c) 2017 Zhuhao Wang

// 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 "nekit/utils/endpoint.h"

#include <boost/assert.hpp>

#include "nekit/utils/error.h"
#include "nekit/utils/log.h"

#undef NECHANNEL
#define NECHANNEL "Endpoint"

namespace nekit {
namespace utils {
Endpoint::Endpoint(const std::string& host, uint16_t port)
    : domain_{host}, port_{port} {
  boost::system::error_code ec;
  address_ = boost::asio::ip::address::from_string(host, ec);

  if (ec) {
    type_ = Type::Domain;
  } else {
    type_ = Type::Address;
  }
}

Endpoint::Endpoint(const boost::asio::ip::address& ip, uint16_t port)
    : type_{Type::Address},
      domain_{ip.to_string()},
      address_{ip},
      port_{port} {}

const Cancelable& Endpoint::Resolve(EventHandler handler) {
  assert(resolver_);

  if (resolved_) {
    NEDEBUG << "Already resolved, does nothing.";

    resolver_->io().post(
        [ handler, cancelable{life_time_cancelable_pointer()} ]() {
          if (cancelable->canceled()) {
            return;
          }

          handler(NEKitErrorCode::NoError);
        });
    return life_time_cancelable();
  }

  return ForceResolve(handler);
}

const Cancelable& Endpoint::ForceResolve(EventHandler handler) {
  assert(resolver_);
  assert(!resolving_);

  NETRACE << "Start resolving domain " << domain_ << ".";

  resolving_ = true;

  resolve_cancelable_ = resolver_->Resolve(
      domain_, ResolverInterface::AddressPreference::Any,
      [ this, handler, cancelable{life_time_cancelable_pointer()} ](
          std::shared_ptr<std::vector<boost::asio::ip::address>> addresses,
          std::error_code ec) {
        if (cancelable->canceled()) {
          return;
        }

        resolving_ = false;
        resolved_ = true;

        if (ec) {
          NEERROR << "Failed to resolve " << domain_ << " due to " << ec << ".";
          error_ = ec;
          resolved_addresses_ = nullptr;
          handler(ec);
          return;
        }

        NEINFO << "Successfully resolved domain " << domain_ << ".";

        resolved_addresses_ = addresses;
        handler(ec);
      });

  return life_time_cancelable();
}

void Endpoint::CancelResolve() {
  if (!resolving_) {
    NEDEBUG << "Canceling a domain not resolving, do nothing.";
    return;
  }

  resolve_cancelable_.Cancel();
}

std::shared_ptr<Endpoint> Endpoint::Dup() const {
  std::shared_ptr<Endpoint> endpoint_;
  switch (type_) {
    case Type::Address:
      endpoint_ = std::make_shared<Endpoint>(address_, port_);
    case Type::Domain:
      endpoint_ = std::make_shared<Endpoint>(domain_, port_);
  }

  endpoint_->set_ip_protocol(ip_protocol_);

  return endpoint_;
}

}  // namespace utils
}  // namespace nekit
<commit_msg>REFACTOR: Update for deprecate asio call<commit_after>// MIT License

// Copyright (c) 2017 Zhuhao Wang

// 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 "nekit/utils/endpoint.h"

#include <boost/assert.hpp>

#include "nekit/utils/error.h"
#include "nekit/utils/log.h"

#undef NECHANNEL
#define NECHANNEL "Endpoint"

namespace nekit {
namespace utils {
Endpoint::Endpoint(const std::string& host, uint16_t port)
    : domain_{host}, port_{port} {
  boost::system::error_code ec;
  address_ = boost::asio::ip::address::from_string(host, ec);

  if (ec) {
    type_ = Type::Domain;
  } else {
    type_ = Type::Address;
  }
}

Endpoint::Endpoint(const boost::asio::ip::address& ip, uint16_t port)
    : type_{Type::Address},
      domain_{ip.to_string()},
      address_{ip},
      port_{port} {}

const Cancelable& Endpoint::Resolve(EventHandler handler) {
  assert(resolver_);

  if (resolved_) {
    NEDEBUG << "Already resolved, does nothing.";

    boost::asio::post(*resolver_->io(),
                      [handler, cancelable{life_time_cancelable_pointer()}]() {
                        if (cancelable->canceled()) {
                          return;
                        }

                        handler(NEKitErrorCode::NoError);
                      });
    return life_time_cancelable();
  }

  return ForceResolve(handler);
}

const Cancelable& Endpoint::ForceResolve(EventHandler handler) {
  assert(resolver_);
  assert(!resolving_);

  NETRACE << "Start resolving domain " << domain_ << ".";

  resolving_ = true;

  resolve_cancelable_ = resolver_->Resolve(
      domain_, ResolverInterface::AddressPreference::Any,
      [this, handler, cancelable{life_time_cancelable_pointer()}](
          std::shared_ptr<std::vector<boost::asio::ip::address>> addresses,
          std::error_code ec) {
        if (cancelable->canceled()) {
          return;
        }

        resolving_ = false;
        resolved_ = true;

        if (ec) {
          NEERROR << "Failed to resolve " << domain_ << " due to " << ec << ".";
          error_ = ec;
          resolved_addresses_ = nullptr;
          handler(ec);
          return;
        }

        NEINFO << "Successfully resolved domain " << domain_ << ".";

        resolved_addresses_ = addresses;
        handler(ec);
      });

  return life_time_cancelable();
}

void Endpoint::CancelResolve() {
  if (!resolving_) {
    NEDEBUG << "Canceling a domain not resolving, do nothing.";
    return;
  }

  resolve_cancelable_.Cancel();
}

std::shared_ptr<Endpoint> Endpoint::Dup() const {
  std::shared_ptr<Endpoint> endpoint_;
  switch (type_) {
    case Type::Address:
      endpoint_ = std::make_shared<Endpoint>(address_, port_);
    case Type::Domain:
      endpoint_ = std::make_shared<Endpoint>(domain_, port_);
  }

  endpoint_->set_ip_protocol(ip_protocol_);

  return endpoint_;
}

}  // namespace utils
}  // namespace nekit
<|endoftext|>


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

#ifndef YDSH_RESULT_HPP
#define YDSH_RESULT_HPP

#include <type_traits>

#include "noncopyable.h"

namespace ydsh {
namespace __detail {

template<typename T>
constexpr T max2(T x, T y) {
    return x > y ? x : y;
}

template<typename T>
constexpr T max(T t) {
    return t;
}

template<typename T, typename U, typename ...R>
constexpr T max(T t, U u, R... r) {
    return max2(t, max(u, std::forward<R>(r)...));
}

constexpr bool andAll(bool b) {
    return b;
}

template <typename ...T>
constexpr bool andAll(bool b, T && ...t) {
    return b && andAll(std::forward<T>(t)...);
}

template <typename T>
constexpr int toTypeIndex(int) {
    return -1;
}

template <typename T, typename F, typename ...R>
constexpr int toTypeIndex(int index) {
    return std::is_same<T, F>::value ? index : toTypeIndex<T, R...>(index + 1);
}

template <std::size_t I, std::size_t N, typename F, typename ...R>
struct TypeByIndex : TypeByIndex<I + 1, N, R...> {};

template <std::size_t N, typename F, typename ...R>
struct TypeByIndex<N, N, F, R...> {
    using type = F;
};

} // namespace __detail

template <typename U, typename ...T>
struct TypeTag {
    static constexpr int value = __detail::toTypeIndex<U, T...>(0);
};

template <std::size_t N, typename ...T>
struct TypeByIndex {
    static_assert(sizeof...(T) > 0, "at least 1 type");
    static_assert(N < sizeof...(T), "out of range");
    using type = typename __detail::TypeByIndex<0, N, T...>::type;
};

// #####################
// ##     Storage     ##
// #####################

template <typename ...T>
struct Storage {
    static_assert(sizeof...(T) > 1, "at least 2 type");

    static constexpr auto size = __detail::max(sizeof(T)...);
    static constexpr auto align = __detail::max(alignof(T)...);

    using type = typename std::aligned_storage<size, align>::type;

    type data;

    template <typename U>
    void obtain(U &&value) {
        static_assert(std::is_rvalue_reference<decltype(value)>::value, "must be rvalue reference");
        static_assert(TypeTag<U, T...>::value > -1, "invalid type");

        using Decayed = typename std::decay<U>::type;
        new (&this->data) Decayed(std::move(value));
    }
};

template <typename T, typename ...R>
inline T &get(Storage<R...> &storage) {
    static_assert(TypeTag<T, R...>::value > -1, "invalid type");

    return *reinterpret_cast<T *>(&storage.data);
}

template <typename T, typename ...R>
inline const T &get(const Storage<R...> &storage) {
    static_assert(TypeTag<T, R...>::value > -1, "invalid type");

    return *reinterpret_cast<const T *>(&storage.data);
}

template <typename T, typename ...R>
inline void destroy(Storage<R...> &storage) {
    get<T>(storage).~T();
}

/**
 *
 * @tparam T
 * @tparam R
 * @param src
 * @param dest
 * must be uninitialized
 */
template <typename T, typename ...R>
inline void move(Storage<R...> &src, Storage<R...> &dest) {
    dest.obtain(std::move(get<T>(src)));
    destroy<T>(src);
}

namespace __detail_union {

template <std::size_t N, typename ...R>
struct Destroyer {
    void operator()(Storage<R...> &storage, int tag) const {
        if(tag == N) {
            using T = typename TypeByIndex<N, R...>::type;
            destroy<T>(storage);
        } else {
            Destroyer<N + 1, R...>()(storage, tag);
        }
    }
};

template <typename ...R>
struct Destroyer<sizeof...(R), R...> {
    void operator()(Storage<R...> &, int) const {}
};

template <std::size_t N, typename ...R>
struct Mover {
    void operator()(Storage<R...> &src, int srcTag, Storage<R...> &dest) const {
        if(srcTag == N) {
            using T = typename TypeByIndex<N, R...>::type;
            move<T>(src, dest);
        } else {
            Mover<N + 1, R...>()(src, srcTag, dest);
        }
    }
};

template <typename ...R>
struct Mover<sizeof...(R), R...> {
    void operator()(Storage<R...> &, int, Storage<R...> &) const {}
};

} // namespace __detail_union

template <typename ...R>
inline void polyDestroy(Storage<R...> &storage, int tag) {
    __detail_union::Destroyer<0, R...>()(storage, tag);
}

/**
 *
 * @tparam N
 * @tparam R
 * @param src
 * @param srcTag
 * @param dest
 * must be uninitialized
 */
template <typename ...R>
inline void polyMove(Storage<R...> &src, int srcTag, Storage<R...> &dest) {
    __detail_union::Mover<0, R...>()(src, srcTag, dest);
}

// ###################
// ##     Union     ##
// ###################

template <typename ...T>
class Union {
private:
    static_assert(__detail::andAll(std::is_move_constructible<T>::value...), "must be move-constructible");

    using StorageType = Storage<T...>;
    StorageType value_;
    int tag_;

public:
    NON_COPYABLE(Union);

    template <typename U>
    explicit Union(U &&value) :tag_(TypeTag<U, T...>::value) {
        this->value_.obtain(std::forward<U>(value));
    }

    Union(Union &&value) : tag_(value.tag()) {
        polyMove(value.value(), this->tag(), this->value());
        value.tag_ = -1;
    }

    ~Union() {
        polyDestroy(this->value(), this->tag());
    }

    StorageType &value() {
        return this->value_;
    }

    const StorageType &value() const {
        return this->value_;
    }

    int tag() const {
        return this->tag_;
    }
};

template <typename T, typename ...R>
inline bool is(const Union<R...> &value) {
    return value.tag() == TypeTag<T, R...>::value;
}

template <typename T, typename ...R>
inline T &get(Union<R...> &value) {
    return get<T>(value.value());
}

template <typename T, typename ...R>
inline const T &get(const Union<R...> &value) {
    return get<T>(value.value());
}

// ####################
// ##     Result     ##
// ####################

template <typename T>
struct OkHolder {
    T value;

    explicit OkHolder(T &&value) : value(std::move(value)) {}
    explicit OkHolder(const T &value) : value(value) {}
};

template <typename E>
struct ErrHolder {
    E value;

    explicit ErrHolder(E &&value) : value(std::move(value)) {}
    explicit ErrHolder(const E &value) : value(value) {}
};

template <typename T, typename Decayed = typename std::decay<T>::type>
OkHolder<Decayed> Ok(T &&value) {
    return OkHolder<Decayed>(std::forward<T>(value));
}

template <typename E, typename Decayed = typename std::decay<E>::type>
ErrHolder<Decayed> Err(E &&value) {
    return ErrHolder<Decayed>(std::forward<E>(value));
}

template <typename T, typename E>
class Result {
private:
    static_assert(std::is_move_constructible<T>::value, "must be move-constructible");
    static_assert(std::is_move_constructible<E>::value, "must be move-constructible");

    using StorageType = Storage<T, E>;
    StorageType value;
    bool ok;

public:
    NON_COPYABLE(Result);

    Result(OkHolder<T> &&okHolder) : ok(true) {
        this->value.obtain(std::move(okHolder.value));
    }

    Result(ErrHolder<E> &&errHolder) : ok(false) {
        this->value.obtain(std::move(errHolder.value));
    }

    Result(Result &&result) noexcept : ok(result.ok) {
        if(this->ok) {
            move<T>(result.value, this->value);
        } else {
            move<E>(result.value, this->value);
        }
    }

    ~Result() {
        if(this->ok) {
            destroy<T>(this->value);
        } else {
            destroy<E>(this->value);
        }
    }

    explicit operator bool() const {
        return this->ok;
    }

    T &asOk() {
        return get<T>(this->value);
    }

    E &asErr() {
        return get<E>(this->value);
    }
};

} // namespace ydsh

#endif //YDSH_RESULT_HPP
<commit_msg>refacotr Result. now use Union<commit_after>/*
 * Copyright (C) 2018 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef YDSH_RESULT_HPP
#define YDSH_RESULT_HPP

#include <type_traits>

#include "noncopyable.h"

namespace ydsh {
namespace __detail {

template<typename T>
constexpr T max2(T x, T y) {
    return x > y ? x : y;
}

template<typename T>
constexpr T max(T t) {
    return t;
}

template<typename T, typename U, typename ...R>
constexpr T max(T t, U u, R... r) {
    return max2(t, max(u, std::forward<R>(r)...));
}

constexpr bool andAll(bool b) {
    return b;
}

template <typename ...T>
constexpr bool andAll(bool b, T && ...t) {
    return b && andAll(std::forward<T>(t)...);
}

template <typename T>
constexpr int toTypeIndex(int) {
    return -1;
}

template <typename T, typename F, typename ...R>
constexpr int toTypeIndex(int index) {
    return std::is_same<T, F>::value ? index : toTypeIndex<T, R...>(index + 1);
}

template <std::size_t I, std::size_t N, typename F, typename ...R>
struct TypeByIndex : TypeByIndex<I + 1, N, R...> {};

template <std::size_t N, typename F, typename ...R>
struct TypeByIndex<N, N, F, R...> {
    using type = F;
};

} // namespace __detail

template <typename U, typename ...T>
struct TypeTag {
    static constexpr int value = __detail::toTypeIndex<U, T...>(0);
};

template <std::size_t N, typename ...T>
struct TypeByIndex {
    static_assert(sizeof...(T) > 0, "at least 1 type");
    static_assert(N < sizeof...(T), "out of range");
    using type = typename __detail::TypeByIndex<0, N, T...>::type;
};

// #####################
// ##     Storage     ##
// #####################

template <typename ...T>
struct Storage {
    static_assert(sizeof...(T) > 1, "at least 2 type");

    static constexpr auto size = __detail::max(sizeof(T)...);
    static constexpr auto align = __detail::max(alignof(T)...);

    using type = typename std::aligned_storage<size, align>::type;

    type data;

    template <typename U>
    void obtain(U &&value) {
        static_assert(std::is_rvalue_reference<decltype(value)>::value, "must be rvalue reference");
        static_assert(TypeTag<U, T...>::value > -1, "invalid type");

        using Decayed = typename std::decay<U>::type;
        new (&this->data) Decayed(std::move(value));
    }
};

template <typename T, typename ...R>
inline T &get(Storage<R...> &storage) {
    static_assert(TypeTag<T, R...>::value > -1, "invalid type");

    return *reinterpret_cast<T *>(&storage.data);
}

template <typename T, typename ...R>
inline const T &get(const Storage<R...> &storage) {
    static_assert(TypeTag<T, R...>::value > -1, "invalid type");

    return *reinterpret_cast<const T *>(&storage.data);
}

template <typename T, typename ...R>
inline void destroy(Storage<R...> &storage) {
    get<T>(storage).~T();
}

/**
 *
 * @tparam T
 * @tparam R
 * @param src
 * @param dest
 * must be uninitialized
 */
template <typename T, typename ...R>
inline void move(Storage<R...> &src, Storage<R...> &dest) {
    dest.obtain(std::move(get<T>(src)));
    destroy<T>(src);
}

namespace __detail_union {

template <std::size_t N, typename ...R>
struct Destroyer {
    void operator()(Storage<R...> &storage, int tag) const {
        if(tag == N) {
            using T = typename TypeByIndex<N, R...>::type;
            destroy<T>(storage);
        } else {
            Destroyer<N + 1, R...>()(storage, tag);
        }
    }
};

template <typename ...R>
struct Destroyer<sizeof...(R), R...> {
    void operator()(Storage<R...> &, int) const {}
};

template <std::size_t N, typename ...R>
struct Mover {
    void operator()(Storage<R...> &src, int srcTag, Storage<R...> &dest) const {
        if(srcTag == N) {
            using T = typename TypeByIndex<N, R...>::type;
            move<T>(src, dest);
        } else {
            Mover<N + 1, R...>()(src, srcTag, dest);
        }
    }
};

template <typename ...R>
struct Mover<sizeof...(R), R...> {
    void operator()(Storage<R...> &, int, Storage<R...> &) const {}
};

} // namespace __detail_union

template <typename ...R>
inline void polyDestroy(Storage<R...> &storage, int tag) {
    __detail_union::Destroyer<0, R...>()(storage, tag);
}

/**
 *
 * @tparam N
 * @tparam R
 * @param src
 * @param srcTag
 * @param dest
 * must be uninitialized
 */
template <typename ...R>
inline void polyMove(Storage<R...> &src, int srcTag, Storage<R...> &dest) {
    __detail_union::Mover<0, R...>()(src, srcTag, dest);
}

// ###################
// ##     Union     ##
// ###################

template <typename ...T>
class Union {
private:
    static_assert(__detail::andAll(std::is_move_constructible<T>::value...), "must be move-constructible");

    using StorageType = Storage<T...>;
    StorageType value_;
    int tag_;

public:
    NON_COPYABLE(Union);

    template <typename U>
    explicit Union(U &&value) :tag_(TypeTag<U, T...>::value) {
        this->value_.obtain(std::forward<U>(value));
    }

    Union(Union &&value) : tag_(value.tag()) {
        polyMove(value.value(), this->tag(), this->value());
        value.tag_ = -1;
    }

    ~Union() {
        polyDestroy(this->value(), this->tag());
    }

    StorageType &value() {
        return this->value_;
    }

    const StorageType &value() const {
        return this->value_;
    }

    int tag() const {
        return this->tag_;
    }
};

template <typename T, typename ...R>
inline bool is(const Union<R...> &value) {
    return value.tag() == TypeTag<T, R...>::value;
}

template <typename T, typename ...R>
inline T &get(Union<R...> &value) {
    return get<T>(value.value());
}

template <typename T, typename ...R>
inline const T &get(const Union<R...> &value) {
    return get<T>(value.value());
}

// ####################
// ##     Result     ##
// ####################

template <typename T>
struct OkHolder {
    T value;

    explicit OkHolder(T &&value) : value(std::move(value)) {}
    explicit OkHolder(const T &value) : value(value) {}
};

template <typename E>
struct ErrHolder {
    E value;

    explicit ErrHolder(E &&value) : value(std::move(value)) {}
    explicit ErrHolder(const E &value) : value(value) {}
};

template <typename T, typename Decayed = typename std::decay<T>::type>
OkHolder<Decayed> Ok(T &&value) {
    return OkHolder<Decayed>(std::forward<T>(value));
}

template <typename E, typename Decayed = typename std::decay<E>::type>
ErrHolder<Decayed> Err(E &&value) {
    return ErrHolder<Decayed>(std::forward<E>(value));
}

template <typename T, typename E>
class Result : public Union<T, E> {
public:
    NON_COPYABLE(Result);

    Result(OkHolder<T> &&okHolder) : Union<T, E>(std::move(okHolder.value)) {}

    Result(ErrHolder<E> &&errHolder) : Union<T, E>(std::move(errHolder.value)) {}

    Result(Result &&result) = default;

    ~Result() = default;

    explicit operator bool() const {
        return is<T>(*this);
    }
    T &asOk() {
        return get<T>(*this);
    }

    E &asErr() {
        return get<E>(*this);
    }
};

} // namespace ydsh

#endif //YDSH_RESULT_HPP
<|endoftext|>


<commit_before>//  Copyright 2016 Peter Georg
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#ifndef pMR_MISC_STRING_H
#define pMR_MISC_STRING_H

#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <array>

namespace pMR
{
    std::string toString();

    template<typename T, typename ...Types>
    std::string toString(std::vector<T> const &arg, Types const &...args);

    template<typename T, std::size_t N, typename ...Types>
    std::string toString(std::array<T, N> const &arg, Types const &...args);

    template<typename T, typename ...Types>
    std::string toString(T const &arg, Types const &...args);

    template<std::size_t N, typename ...Types>
    std::string toString(char const (&arg)[N], Types const &...args);
}

template<typename T, typename ...Types>
std::string pMR::toString(std::vector<T> const &arg, Types const &...args)
{
    std::string str;
    for(auto element : arg)
    {
        str += toString(element);
    }
    str += toString(args...);
    return str;
}

template<typename T, std::size_t N, typename ...Types>
std::string pMR::toString(std::array<T, N> const &arg, Types const &...args)
{
    std::string str;
    for(auto element : arg)
    {
        str += toString(element);
    }
    str += toString(args...);
    return str;
}

template<typename T, typename ...Types>
std::string pMR::toString(T const &arg, Types const &...args)
{
    std::string str;
    std::ostringstream oss;
    oss << arg;
    str += oss.str();
    str += " ";
    str += toString(args...);
    return str;
}

template<std::size_t N, typename ...Types>
std::string pMR::toString(char const (&arg)[N], Types const &...args)
{
    std::string str;
    str += arg;
    str += " ";
    str += toString(args...);
    return str;
}
#endif // pMR_MISC_STRING_H
<commit_msg>Re-format<commit_after>//  Copyright 2016 Peter Georg
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#ifndef pMR_MISC_STRING_H
#define pMR_MISC_STRING_H

#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <array>

namespace pMR
{
    template<typename T, typename ...Types>
    std::string toString(T const &arg, Types const &...args);

    template<std::size_t N, typename ...Types>
    std::string toString(char const (&arg)[N], Types const &...args);

    template<typename T, std::size_t N, typename ...Types>
    std::string toString(std::array<T, N> const &arg, Types const &...args);

    template<typename T, typename ...Types>
    std::string toString(std::vector<T> const &arg, Types const &...args);

    std::string toString();
}

template<typename T, typename ...Types>
std::string pMR::toString(T const &arg, Types const &...args)
{
    std::string str;
    std::ostringstream oss;
    oss << arg;
    str += oss.str();
    str += " ";
    str += toString(args...);
    return str;
}

template<std::size_t N, typename ...Types>
std::string pMR::toString(char const (&arg)[N], Types const &...args)
{
    std::string str;
    str += arg;
    str += " ";
    str += toString(args...);
    return str;
}

template<typename T, std::size_t N, typename ...Types>
std::string pMR::toString(std::array<T, N> const &arg, Types const &...args)
{
    std::string str;
    for(auto element : arg)
    {
        str += toString(element);
    }
    str += toString(args...);
    return str;
}

template<typename T, typename ...Types>
std::string pMR::toString(std::vector<T> const &arg, Types const &...args)
{
    std::string str;
    for(auto element : arg)
    {
        str += toString(element);
    }
    str += toString(args...);
    return str;
}
#endif // pMR_MISC_STRING_H
<|endoftext|>


<commit_before>/*
* Parser Functions
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/parsing.h>
#include <botan/exceptn.h>
#include <botan/charset.h>
#include <botan/loadstor.h>

namespace Botan {

/*
* Convert a string into an integer
*/
u32bit to_u32bit(const std::string& number)
   {
   u32bit n = 0;

   for(std::string::const_iterator j = number.begin(); j != number.end(); ++j)
      {
      const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;

      byte digit = Charset::char2digit(*j);

      if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
         throw Decoding_Error("to_u32bit: Integer overflow");
      n *= 10;
      n += digit;
      }
   return n;
   }

/*
* Convert an integer into a string
*/
std::string to_string(u64bit n, u32bit min_len)
   {
   std::string lenstr;
   if(n)
      {
      while(n > 0)
         {
         lenstr = Charset::digit2char(n % 10) + lenstr;
         n /= 10;
         }
      }
   else
      lenstr = "0";

   while(lenstr.size() < min_len)
      lenstr = "0" + lenstr;

   return lenstr;
   }

/*
* Convert a string into a time duration
*/
u32bit timespec_to_u32bit(const std::string& timespec)
   {
   if(timespec == "")
      return 0;

   const char suffix = timespec[timespec.size()-1];
   std::string value = timespec.substr(0, timespec.size()-1);

   u32bit scale = 1;

   if(Charset::is_digit(suffix))
      value += suffix;
   else if(suffix == 's')
      scale = 1;
   else if(suffix == 'm')
      scale = 60;
   else if(suffix == 'h')
      scale = 60 * 60;
   else if(suffix == 'd')
      scale = 24 * 60 * 60;
   else if(suffix == 'y')
      scale = 365 * 24 * 60 * 60;
   else
      throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec);

   return scale * to_u32bit(value);
   }

/*
* Parse a SCAN-style algorithm name
*/
std::vector<std::string> parse_algorithm_name(const std::string& namex)
   {
   if(namex.find('(') == std::string::npos &&
      namex.find(')') == std::string::npos)
      return std::vector<std::string>(1, namex);

   std::string name = namex, substring;
   std::vector<std::string> elems;
   u32bit level = 0;

   elems.push_back(name.substr(0, name.find('(')));
   name = name.substr(name.find('('));

   for(std::string::const_iterator j = name.begin(); j != name.end(); ++j)
      {
      char c = *j;

      if(c == '(')
         ++level;
      if(c == ')')
         {
         if(level == 1 && j == name.end() - 1)
            {
            if(elems.size() == 1)
               elems.push_back(substring.substr(1));
            else
               elems.push_back(substring);
            return elems;
            }

         if(level == 0 || (level == 1 && j != name.end() - 1))
            throw Invalid_Algorithm_Name(namex);
         --level;
         }

      if(c == ',' && level == 1)
         {
         if(elems.size() == 1)
            elems.push_back(substring.substr(1));
         else
            elems.push_back(substring);
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring != "")
      throw Invalid_Algorithm_Name(namex);

   return elems;
   }

/*
* Split the string on slashes
*/
std::vector<std::string> split_on(const std::string& str, char delim)
   {
   std::vector<std::string> elems;
   if(str == "") return elems;

   std::string substr;
   for(std::string::const_iterator j = str.begin(); j != str.end(); ++j)
      {
      if(*j == delim)
         {
         if(substr != "")
            elems.push_back(substr);
         substr.clear();
         }
      else
         substr += *j;
      }

   if(substr == "")
      throw Format_Error("Unable to split string: " + str);
   elems.push_back(substr);

   return elems;
   }

/*
* Parse an ASN.1 OID string
*/
std::vector<u32bit> parse_asn1_oid(const std::string& oid)
   {
   std::string substring;
   std::vector<u32bit> oid_elems;

   for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
      {
      char c = *j;

      if(c == '.')
         {
         if(substring == "")
            throw Invalid_OID(oid);
         oid_elems.push_back(to_u32bit(substring));
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring == "")
      throw Invalid_OID(oid);
   oid_elems.push_back(to_u32bit(substring));

   if(oid_elems.size() < 2)
      throw Invalid_OID(oid);

   return oid_elems;
   }

/*
* X.500 String Comparison
*/
bool x500_name_cmp(const std::string& name1, const std::string& name2)
   {
   std::string::const_iterator p1 = name1.begin();
   std::string::const_iterator p2 = name2.begin();

   while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
   while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

   while(p1 != name1.end() && p2 != name2.end())
      {
      if(Charset::is_space(*p1))
         {
         if(!Charset::is_space(*p2))
            return false;

         while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
         while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

         if(p1 == name1.end() && p2 == name2.end())
            return true;
         }

      if(!Charset::caseless_cmp(*p1, *p2))
         return false;
      ++p1;
      ++p2;
      }

   while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
   while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

   if((p1 != name1.end()) || (p2 != name2.end()))
      return false;
   return true;
   }

/*
* Convert a decimal-dotted string to binary IP
*/
u32bit string_to_ipv4(const std::string& str)
   {
   std::vector<std::string> parts = split_on(str, '.');

   if(parts.size() != 4)
      throw Decoding_Error("Invalid IP string " + str);

   u32bit ip = 0;

   for(size_t j = 0; j != parts.size(); j++)
      {
      u32bit octet = to_u32bit(parts[j]);

      if(octet > 255)
         throw Decoding_Error("Invalid IP string " + str);

      ip = (ip << 8) | (octet & 0xFF);
      }

   return ip;
   }

/*
* Convert an IP address to decimal-dotted string
*/
std::string ipv4_to_string(u32bit ip)
   {
   std::string str;

   for(size_t j = 0; j != sizeof(ip); j++)
      {
      if(j)
         str += ".";
      str += to_string(get_byte(j, ip));
      }

   return str;
   }

}
<commit_msg>In to_u32bit, ignore space characters in input<commit_after>/*
* Parser Functions
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/parsing.h>
#include <botan/exceptn.h>
#include <botan/charset.h>
#include <botan/loadstor.h>

namespace Botan {

/*
* Convert a string into an integer
*/
u32bit to_u32bit(const std::string& number)
   {
   u32bit n = 0;

   for(std::string::const_iterator j = number.begin(); j != number.end(); ++j)
      {
      const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;

      if(*j == ' ')
         continue;

      byte digit = Charset::char2digit(*j);

      if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
         throw Decoding_Error("to_u32bit: Integer overflow");
      n *= 10;
      n += digit;
      }
   return n;
   }

/*
* Convert an integer into a string
*/
std::string to_string(u64bit n, u32bit min_len)
   {
   std::string lenstr;
   if(n)
      {
      while(n > 0)
         {
         lenstr = Charset::digit2char(n % 10) + lenstr;
         n /= 10;
         }
      }
   else
      lenstr = "0";

   while(lenstr.size() < min_len)
      lenstr = "0" + lenstr;

   return lenstr;
   }

/*
* Convert a string into a time duration
*/
u32bit timespec_to_u32bit(const std::string& timespec)
   {
   if(timespec == "")
      return 0;

   const char suffix = timespec[timespec.size()-1];
   std::string value = timespec.substr(0, timespec.size()-1);

   u32bit scale = 1;

   if(Charset::is_digit(suffix))
      value += suffix;
   else if(suffix == 's')
      scale = 1;
   else if(suffix == 'm')
      scale = 60;
   else if(suffix == 'h')
      scale = 60 * 60;
   else if(suffix == 'd')
      scale = 24 * 60 * 60;
   else if(suffix == 'y')
      scale = 365 * 24 * 60 * 60;
   else
      throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec);

   return scale * to_u32bit(value);
   }

/*
* Parse a SCAN-style algorithm name
*/
std::vector<std::string> parse_algorithm_name(const std::string& namex)
   {
   if(namex.find('(') == std::string::npos &&
      namex.find(')') == std::string::npos)
      return std::vector<std::string>(1, namex);

   std::string name = namex, substring;
   std::vector<std::string> elems;
   u32bit level = 0;

   elems.push_back(name.substr(0, name.find('(')));
   name = name.substr(name.find('('));

   for(std::string::const_iterator j = name.begin(); j != name.end(); ++j)
      {
      char c = *j;

      if(c == '(')
         ++level;
      if(c == ')')
         {
         if(level == 1 && j == name.end() - 1)
            {
            if(elems.size() == 1)
               elems.push_back(substring.substr(1));
            else
               elems.push_back(substring);
            return elems;
            }

         if(level == 0 || (level == 1 && j != name.end() - 1))
            throw Invalid_Algorithm_Name(namex);
         --level;
         }

      if(c == ',' && level == 1)
         {
         if(elems.size() == 1)
            elems.push_back(substring.substr(1));
         else
            elems.push_back(substring);
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring != "")
      throw Invalid_Algorithm_Name(namex);

   return elems;
   }

/*
* Split the string on slashes
*/
std::vector<std::string> split_on(const std::string& str, char delim)
   {
   std::vector<std::string> elems;
   if(str == "") return elems;

   std::string substr;
   for(std::string::const_iterator j = str.begin(); j != str.end(); ++j)
      {
      if(*j == delim)
         {
         if(substr != "")
            elems.push_back(substr);
         substr.clear();
         }
      else
         substr += *j;
      }

   if(substr == "")
      throw Format_Error("Unable to split string: " + str);
   elems.push_back(substr);

   return elems;
   }

/*
* Parse an ASN.1 OID string
*/
std::vector<u32bit> parse_asn1_oid(const std::string& oid)
   {
   std::string substring;
   std::vector<u32bit> oid_elems;

   for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
      {
      char c = *j;

      if(c == '.')
         {
         if(substring == "")
            throw Invalid_OID(oid);
         oid_elems.push_back(to_u32bit(substring));
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring == "")
      throw Invalid_OID(oid);
   oid_elems.push_back(to_u32bit(substring));

   if(oid_elems.size() < 2)
      throw Invalid_OID(oid);

   return oid_elems;
   }

/*
* X.500 String Comparison
*/
bool x500_name_cmp(const std::string& name1, const std::string& name2)
   {
   std::string::const_iterator p1 = name1.begin();
   std::string::const_iterator p2 = name2.begin();

   while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
   while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

   while(p1 != name1.end() && p2 != name2.end())
      {
      if(Charset::is_space(*p1))
         {
         if(!Charset::is_space(*p2))
            return false;

         while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
         while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

         if(p1 == name1.end() && p2 == name2.end())
            return true;
         }

      if(!Charset::caseless_cmp(*p1, *p2))
         return false;
      ++p1;
      ++p2;
      }

   while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
   while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;

   if((p1 != name1.end()) || (p2 != name2.end()))
      return false;
   return true;
   }

/*
* Convert a decimal-dotted string to binary IP
*/
u32bit string_to_ipv4(const std::string& str)
   {
   std::vector<std::string> parts = split_on(str, '.');

   if(parts.size() != 4)
      throw Decoding_Error("Invalid IP string " + str);

   u32bit ip = 0;

   for(size_t j = 0; j != parts.size(); j++)
      {
      u32bit octet = to_u32bit(parts[j]);

      if(octet > 255)
         throw Decoding_Error("Invalid IP string " + str);

      ip = (ip << 8) | (octet & 0xFF);
      }

   return ip;
   }

/*
* Convert an IP address to decimal-dotted string
*/
std::string ipv4_to_string(u32bit ip)
   {
   std::string str;

   for(size_t j = 0; j != sizeof(ip); j++)
      {
      if(j)
         str += ".";
      str += to_string(get_byte(j, ip));
      }

   return str;
   }

}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Copyright (c) 2015-2016 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "arith_uint256.h"
#include "chain.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
    unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

    // mvhf-bu genesis block reset the difficulty target
    if (pindexLast->nHeight == params.MVFActivateForkHeight() )
    {
    	return nProofOfWorkLimit;
    }

    // Only change once per difficulty adjustment interval
    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval(pindexLast->nHeight) != 0)
    {
        if (params.fPowAllowMinDifficultyBlocks)
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval(pindexLast->nHeight) != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Go back by what we want to be 14 days worth of blocks
    int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval(pindexLast->nHeight)-1);
    assert(nHeightFirst >= 0);
    const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
    assert(pindexFirst);

    return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);

    //mvhf-bu target time span while within the re-target period
    int64_t nTargetTimespan = params.nPowTargetTimespan; // the original 2016 blocks

	// During the MVF Re-target Period after the fork block the target time span starts at 1 block until 12 blocks
	if (pindexLast->nHeight > params.MVFActivateForkHeight() && pindexLast->nHeight < params.nMVFRetargetPeriodEnd() )
	{
		nTargetTimespan = params.nPowTargetSpacing * (pindexLast->nHeight - params.MVFActivateForkHeight());
		if (nTargetTimespan > params.nPowTargetSpacing * 12) nTargetTimespan = params.nPowTargetSpacing * 12;
	}

	// During the first 12 blocks after the fork abrupt changes are permitted
	if (nTargetTimespan >= params.nPowTargetSpacing * 12)
	{
		// prevent abrupt changes to target
		if (nActualTimespan < params.nPowTargetTimespan/4)
			nActualTimespan = params.nPowTargetTimespan/4;
		if (nActualTimespan > params.nPowTargetTimespan*4)
			nActualTimespan = params.nPowTargetTimespan*4;
	}

    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    arith_uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    bnNew *= nActualTimespan;
    bnNew /= nTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

    /// debug print
    LogPrintf("GetNextWorkRequired RETARGET\n");
    LogPrintf("nTargetTimespan = %d    nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
        return error("CheckProofOfWork(): nBits below minimum work");

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) > bnTarget)
      return error("CheckProofOfWork(): hash %s doesn't match nBits 0x%x",hash.ToString(),nBits);

    return true;
}

arith_uint256 GetBlockProof(const CBlockIndex& block)
{
    arith_uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a arith_uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}

int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
{
    arith_uint256 r;
    int sign = 1;
    if (to.nChainWork > from.nChainWork) {
        r = to.nChainWork - from.nChainWork;
    } else {
        r = from.nChainWork - to.nChainWork;
        sign = -1;
    }
    r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
    if (r.bits() > 63) {
        return sign * std::numeric_limits<int64_t>::max();
    }
    return sign * r.GetLow64();
}
<commit_msg>Extend time span.<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Copyright (c) 2015-2016 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "arith_uint256.h"
#include "chain.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
    unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

    // mvhf-bu genesis block reset the difficulty target
    if (pindexLast->nHeight == params.MVFActivateForkHeight() )
    {
    	return nProofOfWorkLimit;
    }

    // Only change once per difficulty adjustment interval
    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval(pindexLast->nHeight) != 0)
    {
        if (params.fPowAllowMinDifficultyBlocks)
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval(pindexLast->nHeight) != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Go back by what we want to be 14 days worth of blocks
    int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval(pindexLast->nHeight)-1);
    assert(nHeightFirst >= 0);
    const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
    assert(pindexFirst);

    return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);

    //mvhf-bu target time span while within the re-target period
    int64_t nTargetTimespan = params.nPowTargetTimespan; // the original 2016 blocks

	// During the MVF Re-target Period after the fork block the target time span starts at 1 block until 2016 blocks
	if (pindexLast->nHeight > params.MVFActivateForkHeight() && pindexLast->nHeight < params.nMVFRetargetPeriodEnd() )
	{
		nTargetTimespan = params.nPowTargetSpacing * (pindexLast->nHeight - params.MVFActivateForkHeight());
		// Limit the time span to 2016
		if (nTargetTimespan > params.nPowTargetSpacing * 2016) nTargetTimespan = params.nPowTargetSpacing * 2016;
	}

	// During the first 12 blocks after the fork abrupt changes are permitted
	if (nTargetTimespan >= params.nPowTargetSpacing * 12)
	{
		// prevent abrupt changes to target
		if (nActualTimespan < params.nPowTargetTimespan/4)
			nActualTimespan = params.nPowTargetTimespan/4;
		if (nActualTimespan > params.nPowTargetTimespan*4)
			nActualTimespan = params.nPowTargetTimespan*4;
	}

    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    arith_uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    bnNew *= nActualTimespan;
    bnNew /= nTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

    /// debug print
    LogPrintf("GetNextWorkRequired RETARGET\n");
    LogPrintf("nTargetTimespan = %d    nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
        return error("CheckProofOfWork(): nBits below minimum work");

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) > bnTarget)
      return error("CheckProofOfWork(): hash %s doesn't match nBits 0x%x",hash.ToString(),nBits);

    return true;
}

arith_uint256 GetBlockProof(const CBlockIndex& block)
{
    arith_uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a arith_uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}

int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
{
    arith_uint256 r;
    int sign = 1;
    if (to.nChainWork > from.nChainWork) {
        r = to.nChainWork - from.nChainWork;
    } else {
        r = from.nChainWork - to.nChainWork;
        sign = -1;
    }
    r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
    if (r.bits() > 63) {
        return sign * std::numeric_limits<int64_t>::max();
    }
    return sign * r.GetLow64();
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2018 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "chain.h"
#include "chainparams.h"
#include "main.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

#include <math.h>

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader* pblock)
{
    if (Params().NetworkID() == CBaseChainParams::REGTEST)
        return pindexLast->nBits;

    /* current difficulty formula, pivx - DarkGravity v3, written by Evan Duffield - evan@dashpay.io */
    const CBlockIndex* BlockLastSolved = pindexLast;
    const CBlockIndex* BlockReading = pindexLast;
    int64_t nActualTimespan = 0;
    int64_t LastBlockTime = 0;
    int64_t PastBlocksMin = 24;
    int64_t PastBlocksMax = 24;
    int64_t CountBlocks = 0;
    uint256 PastDifficultyAverage;
    uint256 PastDifficultyAveragePrev;

    if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) {
        return Params().ProofOfWorkLimit().GetCompact();
    }

    if (pindexLast->nHeight >= Params().LAST_POW_BLOCK()) {
        const bool fTimeV2 = Params().IsTimeProtocolV2(pindexLast->nHeight+1);
        const uint256 bnTargetLimit = Params().ProofOfStakeLimit(fTimeV2);
        const int64_t nTargetSpacing = Params().TargetSpacing();
        const int64_t nTargetTimespan = Params().TargetTimespan(fTimeV2);

        int64_t nActualSpacing = 0;
        if (pindexLast->nHeight != 0)
            nActualSpacing = pindexLast->GetBlockTime() - pindexLast->pprev->GetBlockTime();
        if (nActualSpacing < 0)
            nActualSpacing = 1;
        if (fTimeV2 && nActualSpacing > nTargetSpacing*10)
            nActualSpacing = nTargetSpacing*10;

        // ppcoin: target change every block
        // ppcoin: retarget with exponential moving toward target spacing
        uint256 bnNew;
        // on first block with V2 time protocol, reduce the difficulty by a factor 16
        if (fTimeV2 && !Params().IsTimeProtocolV2(pindexLast->nHeight)) {
            bnNew.SetCompact(pindexLast->nBits << 4);
        } else {
            bnNew.SetCompact(pindexLast->nBits);
        }

        int64_t nInterval = nTargetTimespan / nTargetSpacing;
        bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
        bnNew /= ((nInterval + 1) * nTargetSpacing);

        if (bnNew <= 0 || bnNew > bnTargetLimit)
            bnNew = bnTargetLimit;

        return bnNew.GetCompact();
    }

    for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
        if (PastBlocksMax > 0 && i > PastBlocksMax) {
            break;
        }
        CountBlocks++;

        if (CountBlocks <= PastBlocksMin) {
            if (CountBlocks == 1) {
                PastDifficultyAverage.SetCompact(BlockReading->nBits);
            } else {
                PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks) + (uint256().SetCompact(BlockReading->nBits))) / (CountBlocks + 1);
            }
            PastDifficultyAveragePrev = PastDifficultyAverage;
        }

        if (LastBlockTime > 0) {
            int64_t Diff = (LastBlockTime - BlockReading->GetBlockTime());
            nActualTimespan += Diff;
        }
        LastBlockTime = BlockReading->GetBlockTime();

        if (BlockReading->pprev == NULL) {
            assert(BlockReading);
            break;
        }
        BlockReading = BlockReading->pprev;
    }

    uint256 bnNew(PastDifficultyAverage);

    int64_t _nTargetTimespan = CountBlocks * Params().TargetSpacing();

    if (nActualTimespan < _nTargetTimespan / 3)
        nActualTimespan = _nTargetTimespan / 3;
    if (nActualTimespan > _nTargetTimespan * 3)
        nActualTimespan = _nTargetTimespan * 3;

    // Retarget
    bnNew *= nActualTimespan;
    bnNew /= _nTargetTimespan;

    if (bnNew > Params().ProofOfWorkLimit()) {
        bnNew = Params().ProofOfWorkLimit();
    }

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    uint256 bnTarget;

    if (Params().SkipProofOfWorkCheck())
        return true;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget) {
        if (Params().MineBlocksOnDemand())
            return false;
        else
            return error("CheckProofOfWork() : hash doesn't match nBits");
    }

    return true;
}

uint256 GetBlockProof(const CBlockIndex& block)
{
    uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}
<commit_msg>[Consensus] Fix difficulty adjustment on first block of timeproto V2<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2018 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "chain.h"
#include "chainparams.h"
#include "main.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

#include <math.h>

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader* pblock)
{
    if (Params().NetworkID() == CBaseChainParams::REGTEST)
        return pindexLast->nBits;

    /* current difficulty formula, pivx - DarkGravity v3, written by Evan Duffield - evan@dashpay.io */
    const CBlockIndex* BlockLastSolved = pindexLast;
    const CBlockIndex* BlockReading = pindexLast;
    int64_t nActualTimespan = 0;
    int64_t LastBlockTime = 0;
    int64_t PastBlocksMin = 24;
    int64_t PastBlocksMax = 24;
    int64_t CountBlocks = 0;
    uint256 PastDifficultyAverage;
    uint256 PastDifficultyAveragePrev;

    if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) {
        return Params().ProofOfWorkLimit().GetCompact();
    }

    if (pindexLast->nHeight >= Params().LAST_POW_BLOCK()) {
        const bool fTimeV2 = Params().IsTimeProtocolV2(pindexLast->nHeight+1);
        const uint256 bnTargetLimit = Params().ProofOfStakeLimit(fTimeV2);
        const int64_t nTargetSpacing = Params().TargetSpacing();
        const int64_t nTargetTimespan = Params().TargetTimespan(fTimeV2);

        int64_t nActualSpacing = 0;
        if (pindexLast->nHeight != 0)
            nActualSpacing = pindexLast->GetBlockTime() - pindexLast->pprev->GetBlockTime();
        if (nActualSpacing < 0)
            nActualSpacing = 1;
        if (fTimeV2 && nActualSpacing > nTargetSpacing*10)
            nActualSpacing = nTargetSpacing*10;

        // ppcoin: target change every block
        // ppcoin: retarget with exponential moving toward target spacing
        uint256 bnNew;
        bnNew.SetCompact(pindexLast->nBits);

        // on first block with V2 time protocol, reduce the difficulty by a factor 16
        if (fTimeV2 && !Params().IsTimeProtocolV2(pindexLast->nHeight))
            bnNew <<= 4;

        int64_t nInterval = nTargetTimespan / nTargetSpacing;
        bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
        bnNew /= ((nInterval + 1) * nTargetSpacing);

        if (bnNew <= 0 || bnNew > bnTargetLimit)
            bnNew = bnTargetLimit;

        return bnNew.GetCompact();
    }

    for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
        if (PastBlocksMax > 0 && i > PastBlocksMax) {
            break;
        }
        CountBlocks++;

        if (CountBlocks <= PastBlocksMin) {
            if (CountBlocks == 1) {
                PastDifficultyAverage.SetCompact(BlockReading->nBits);
            } else {
                PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks) + (uint256().SetCompact(BlockReading->nBits))) / (CountBlocks + 1);
            }
            PastDifficultyAveragePrev = PastDifficultyAverage;
        }

        if (LastBlockTime > 0) {
            int64_t Diff = (LastBlockTime - BlockReading->GetBlockTime());
            nActualTimespan += Diff;
        }
        LastBlockTime = BlockReading->GetBlockTime();

        if (BlockReading->pprev == NULL) {
            assert(BlockReading);
            break;
        }
        BlockReading = BlockReading->pprev;
    }

    uint256 bnNew(PastDifficultyAverage);

    int64_t _nTargetTimespan = CountBlocks * Params().TargetSpacing();

    if (nActualTimespan < _nTargetTimespan / 3)
        nActualTimespan = _nTargetTimespan / 3;
    if (nActualTimespan > _nTargetTimespan * 3)
        nActualTimespan = _nTargetTimespan * 3;

    // Retarget
    bnNew *= nActualTimespan;
    bnNew /= _nTargetTimespan;

    if (bnNew > Params().ProofOfWorkLimit()) {
        bnNew = Params().ProofOfWorkLimit();
    }

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    uint256 bnTarget;

    if (Params().SkipProofOfWorkCheck())
        return true;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget) {
        if (Params().MineBlocksOnDemand())
            return false;
        else
            return error("CheckProofOfWork() : hash doesn't match nBits");
    }

    return true;
}

uint256 GetBlockProof(const CBlockIndex& block)
{
    uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}
<|endoftext|>


<commit_before>#include <node.h>
#include <nan.h>
#include <Python.h>
#include <iostream>
#include <cassert>

#include "pyjsobject.h"
#include "pyjstypeconv.h"

using namespace Nan;
using v8::Value;
using v8::Local;
using v8::Object;
using v8::FunctionTemplate;
using v8::String;

void PyjsEval(const FunctionCallbackInfo<Value>& args) {
    Local<String> script = args[0]->ToString();
    PyObject *dict = PyDict_New();
    PyObject *object = PyRun_String(*static_cast<String::Utf8Value>(script), Py_single_input, dict, dict);
    Py_DECREF(dict);
    if (object == nullptr) {
        // exception
        PyErr_Print();
        PyErr_Clear();
    }
    args.GetReturnValue().Set(PyjsObject::NewInstance(object));
}

void PyjsBuiltins(const FunctionCallbackInfo<Value> &args) {
    PyObject *builtins = PyEval_GetBuiltins();
    assert(builtins);
    args.GetReturnValue().Set(PyToJs(builtins));
}

void PyjsImport(const Nan::FunctionCallbackInfo<v8::Value> &args) {
    Local<String> name = args[0]->ToString();
    PyObject *object = PyImport_ImportModule(*static_cast<String::Utf8Value>(name));
    args.GetReturnValue().Set(PyjsObject::NewInstance(object));
}

void Init(Local<Object> exports) {
    // python initialize
    Py_Initialize();
    /*
    PyObject *sysPath = PySys_GetObject("path");
    PyObject *path = PyUnicode_FromString("");
    int result = PyList_Insert(sysPath, 0, path);
    assert(result != -1);
    Py_DECREF(path);
    */
    PyjsObject::Init(exports);

    Nan::SetMethod(exports, "eval", PyjsEval);
    Nan::SetMethod(exports, "builtins", PyjsBuiltins);
    Nan::SetMethod(exports, "import", PyjsImport);
}

NODE_MODULE(pyjs, Init)
<commit_msg>mistake!<commit_after>#include <node.h>
#include <nan.h>
#include <Python.h>
#include <iostream>
#include <cassert>

#include "pyjsobject.h"
#include "pyjstypeconv.h"

using namespace Nan;
using v8::Value;
using v8::Local;
using v8::Object;
using v8::FunctionTemplate;
using v8::String;

void PyjsEval(const FunctionCallbackInfo<Value>& args) {
    Local<String> script = args[0]->ToString();
    PyObject *dict = PyDict_New();
    PyObject *object = PyRun_String(*static_cast<String::Utf8Value>(script), Py_single_input, dict, dict);
    Py_DECREF(dict);
    if (object == nullptr) {
        // exception
        PyErr_Print();
        PyErr_Clear();
    }
    args.GetReturnValue().Set(PyjsObject::NewInstance(object));
}

void PyjsBuiltins(const FunctionCallbackInfo<Value> &args) {
    PyObject *builtins = PyEval_GetBuiltins();
    assert(builtins);
    args.GetReturnValue().Set(PyToJs(builtins));
}

void PyjsImport(const Nan::FunctionCallbackInfo<v8::Value> &args) {
    Local<String> name = args[0]->ToString();
    PyObject *object = PyImport_ImportModule(*static_cast<String::Utf8Value>(name));
    args.GetReturnValue().Set(PyjsObject::NewInstance(object));
}

void Init(Local<Object> exports) {
    // python initialize
    Py_Initialize();
    PyObject *sysPath = PySys_GetObject("path");
    PyObject *path = PyUnicode_FromString("");
    int result = PyList_Insert(sysPath, 0, path);
    assert(result != -1);
    Py_DECREF(path);
    PyjsObject::Init(exports);

    Nan::SetMethod(exports, "eval", PyjsEval);
    Nan::SetMethod(exports, "builtins", PyjsBuiltins);
    Nan::SetMethod(exports, "import", PyjsImport);
}

NODE_MODULE(pyjs, Init)
<|endoftext|>


<commit_before>#include "ray.hpp"

#include <math.h>
#include <array>
#include <algorithm>

#include "constants.hpp"
#include "box2d.hpp"

Ray::Ray(const Point2D & origin,
         const Point2D & direction)
  : m_origin(origin)
{
  m_direction = normalize(direction);
}

void Ray::swap(Ray & rhs)
{
  std::swap(m_origin, rhs.m_origin);
  std::swap(m_direction, rhs.m_direction);
}

Ray::Ray(Ray && rhs)
{
  swap(rhs);
}

Ray & Ray::operator=(Ray && rhs)
{
  swap(rhs);
  return *this;
}

bool Ray::operator ==(Ray const & rhs) const
{
  if (this == &rhs) { return true; }

  if (this->m_direction != rhs.direction()) { return false; }
  if (this->m_origin != rhs.origin()) { return false; }

  return true;
}

bool Ray::operator !=(Ray const & rhs) const
{
  return !(this->operator ==(rhs));
}

Point2D Ray::normalize(Point2D direction)
{
  float x = checkZeroDenominator(direction.x());
  float y = checkZeroDenominator(direction.y());

  float length = sqrt(pow(x, 2.0) + pow(y, 2.0));

  direction /= length;

  return direction;
}

Ray & Ray::operator=(const Ray & rhs)
{
  Ray tmp(rhs);
  swap(tmp);
  return *this;
}

bool Ray::checkIntersection(
    Ray const & ray,
    Box2D const & box)
{
  // Check if a point inside a box.
  if (Box2D::checkInside(box, ray.origin()))
  {
    return true;
  }

  bool isSpecial = false;

  // Recalculate box points.
  // Use the point as an origin of a coordinate system for the box.
  float xBoxMinLower = box.boxMin().x() - ray.origin().x();
  float xBoxMaxUpper = box.boxMax().x() - ray.origin().x();

  float yBoxMinLower = box.boxMin().y() - ray.origin().y();
  float yBoxMaxUpper = box.boxMax().y() - ray.origin().y();

  float xBoxMinUpper = xBoxMinLower;
  float yBoxMinUpper = yBoxMaxUpper;

  float xBoxMaxLower = xBoxMaxUpper;
  float yBoxMaxLower = yBoxMinLower;

  float xRay = ray.direction().x();
  float yRay = ray.direction().y();

  // It handels special case when rectangle intersepts x-axis
  // to the right from an origin point of a ray.
  if (xRay < xBoxMinLower)
  {
    isSpecial = true;
  }

  // Check if the x coordinate is zero.
  xRay = checkZeroDenominator(xRay);
  xBoxMinLower = checkZeroDenominator(xBoxMinLower);
  xBoxMaxUpper = checkZeroDenominator(xBoxMaxUpper);
  xBoxMinUpper = checkZeroDenominator(xBoxMinUpper);
  xBoxMaxLower = checkZeroDenominator(xBoxMaxLower);

  // Calculate an anlge for the current point
  // and convert the angle to degrees.
  float angleRay = convertRadianToDegrees(
        std::atan(yRay / xRay));

  float angleBoxMinLower = convertRadianToDegrees(
        std::atan(yBoxMinLower / xBoxMinLower));

  float angleBoxMaxUpper = convertRadianToDegrees(
        std::atan(yBoxMaxUpper / xBoxMaxUpper));

  float angleBoxMinUpper = convertRadianToDegrees(
        std::atan(yBoxMinUpper / xBoxMinUpper));

  float angleBoxMaxLower = convertRadianToDegrees(
        std::atan(yBoxMaxLower / xBoxMaxLower));

  // Correct a value of the angle if needed.
  angleRay = recalculateAngle(
        xRay, yRay, angleRay);

  angleBoxMinLower = recalculateAngle(
        xBoxMinLower, yBoxMinLower, angleBoxMinLower);

  angleBoxMaxUpper = recalculateAngle(
        xBoxMaxUpper, yBoxMaxUpper, angleBoxMaxUpper);

  angleBoxMinUpper = recalculateAngle(
        xBoxMinUpper, yBoxMinUpper, angleBoxMinUpper);

  angleBoxMaxLower = recalculateAngle(
        xBoxMaxLower, yBoxMaxLower, angleBoxMaxLower);

  // Combine all angles for the box points.
  std::array<float, 4> angles = {
    angleBoxMinLower, angleBoxMaxUpper,
    angleBoxMinUpper, angleBoxMaxLower
  };

  if (isSpecial)
  {
    // It finds to angles.
    // Maximum angle in the first quater
    // and the minimun angle in the fouth quater.
    float angleMaxFirstQuater = 0.0f;
    float angleMinFourthQuater = 360.0f;

    for (auto const & item : angles)
    {
      if (item < 90.0f)
      {
        if (angleMaxFirstQuater < item)
        {
          angleMaxFirstQuater = item;
        }
      }
      else if (item > 270.0f)
      {
        if (angleMinFourthQuater > item)
        {
          angleMinFourthQuater = item;
        }
      }
    }

    // Compare the ray angle with
    // the max angle in the first quater
    // and the min angle in the fouth quater.
    if (angleRay <= angleMaxFirstQuater &&
        angleRay >= angleMinFourthQuater) {
      return true;
    }
  }
  else
  {
    // Find a min and max angles for the box points.
    auto result = std::minmax_element(
          std::begin(angles), std::end(angles));

    // Compare the ray angle with the min
    // and max angles for the box points.
    if (*result.first <= angleRay &&
        angleRay <= *result.second) {
      return true;
    }
  }

  return false;
}

float Ray::convertRadianToDegrees(float const & angle)
{
  return angle / Constants::PI * 180;
}

float Ray::recalculateAngle(float const & x,
                            float const & y,
                            float const & angle)
{
  float correctedAngle = 0.0f;

  // The second quarter.
  if (y > (0.0f - Constants::kEps) &&
      x < (0.0f + Constants::kEps))
  {
    correctedAngle = 180.0f - abs(angle);
  }

  // The third quarter.
  if (y < 0.0f &&
      x < (0.0f + Constants::kEps))
  {
    correctedAngle = 180.0f + abs(angle);
  }

  // The fouth quarter.
  if (y < 0.0f &&
      x > 0.0f)
  {
    correctedAngle = 360.0f - abs(angle);
  }

  return correctedAngle;
}

float Ray::checkZeroDenominator(float const & value)
{
  float tmp = value;

  if (abs(tmp) < Constants::kEps)
  {
    tmp = Constants::kEps;
  }

  return tmp;
}

void Ray::setOrigin(const Point2D & origin)
{
  m_origin = origin;
}

void Ray::setDirection(const Point2D & direction)
{
  m_direction = normalize(direction);
}

std::ostream & operator <<(std::ostream & os,
                           Ray const & rhs)
{
  os << "origin: " << rhs.origin() << "; "
     << "direction: " << rhs.direction() << std::endl;
  return os;
}
<commit_msg>reformat code<commit_after>#include "ray.hpp"

#include <math.h>
#include <array>
#include <algorithm>

#include "constants.hpp"
#include "box2d.hpp"

Ray::Ray(const Point2D & origin,
         const Point2D & direction)
  : m_origin(origin)
{
  m_direction = normalize(direction);
}

void Ray::swap(Ray & rhs)
{
  std::swap(m_origin, rhs.m_origin);
  std::swap(m_direction, rhs.m_direction);
}

Ray::Ray(Ray && rhs)
{
  swap(rhs);
}

Ray & Ray::operator=(Ray && rhs)
{
  swap(rhs);
  return *this;
}

bool Ray::operator ==(Ray const & rhs) const
{
  if (this == &rhs) { return true; }

  if (this->m_direction != rhs.direction()) { return false; }
  if (this->m_origin != rhs.origin()) { return false; }

  return true;
}

bool Ray::operator !=(Ray const & rhs) const
{
  return !(this->operator ==(rhs));
}

Point2D Ray::normalize(Point2D direction)
{
  float x = checkZeroDenominator(direction.x());
  float y = checkZeroDenominator(direction.y());

  float length = sqrt(pow(x, 2.0) + pow(y, 2.0));

  direction /= length;

  return direction;
}

Ray & Ray::operator=(const Ray & rhs)
{
  Ray tmp(rhs);
  swap(tmp);
  return *this;
}

bool Ray::checkIntersection(
    Ray const & ray,
    Box2D const & box)
{
  // Check if a point inside a box.
  if (Box2D::checkInside(box, ray.origin()))
  {
    return true;
  }

  bool isSpecial = false;

  // Recalculate box points.
  // Use the point as an origin of a coordinate system for the box.
  float xBoxMinLower = box.boxMin().x() - ray.origin().x();
  float xBoxMaxUpper = box.boxMax().x() - ray.origin().x();

  float yBoxMinLower = box.boxMin().y() - ray.origin().y();
  float yBoxMaxUpper = box.boxMax().y() - ray.origin().y();

  float xBoxMinUpper = xBoxMinLower;
  float yBoxMinUpper = yBoxMaxUpper;

  float xBoxMaxLower = xBoxMaxUpper;
  float yBoxMaxLower = yBoxMinLower;

  float xRay = ray.direction().x();
  float yRay = ray.direction().y();

  // It handels special case when rectangle intersepts x-axis
  // to the right from an origin point of a ray.
  if (xRay < xBoxMinLower)
  {
    isSpecial = true;
  }

  // Check if the x coordinate is zero.
  xRay = checkZeroDenominator(xRay);
  xBoxMinLower = checkZeroDenominator(xBoxMinLower);
  xBoxMaxUpper = checkZeroDenominator(xBoxMaxUpper);
  xBoxMinUpper = checkZeroDenominator(xBoxMinUpper);
  xBoxMaxLower = checkZeroDenominator(xBoxMaxLower);

  // Calculate an anlge for the current point
  // and convert the angle to degrees.
  float angleRay = convertRadianToDegrees(
        std::atan(yRay / xRay));

  float angleBoxMinLower = convertRadianToDegrees(
        std::atan(yBoxMinLower / xBoxMinLower));

  float angleBoxMaxUpper = convertRadianToDegrees(
        std::atan(yBoxMaxUpper / xBoxMaxUpper));

  float angleBoxMinUpper = convertRadianToDegrees(
        std::atan(yBoxMinUpper / xBoxMinUpper));

  float angleBoxMaxLower = convertRadianToDegrees(
        std::atan(yBoxMaxLower / xBoxMaxLower));

  // Correct a value of the angle if needed.
  angleRay = recalculateAngle(
        xRay, yRay, angleRay);

  angleBoxMinLower = recalculateAngle(
        xBoxMinLower, yBoxMinLower, angleBoxMinLower);

  angleBoxMaxUpper = recalculateAngle(
        xBoxMaxUpper, yBoxMaxUpper, angleBoxMaxUpper);

  angleBoxMinUpper = recalculateAngle(
        xBoxMinUpper, yBoxMinUpper, angleBoxMinUpper);

  angleBoxMaxLower = recalculateAngle(
        xBoxMaxLower, yBoxMaxLower, angleBoxMaxLower);

  // Combine all angles for the box points.
  std::array<float, 4> angles = {
    angleBoxMinLower, angleBoxMaxUpper,
    angleBoxMinUpper, angleBoxMaxLower
  };

  if (isSpecial)
  {
    // It finds to angles.
    // Maximum angle in the first quater
    // and the minimun angle in the fouth quater.
    float angleMaxFirstQuater = 0.0f;
    float angleMinFourthQuater = 360.0f;

    for (auto const & item : angles)
    {
      if (item < 90.0f)
      {
        if (angleMaxFirstQuater < item)
        {
          angleMaxFirstQuater = item;
        }
      }
      else if (item > 270.0f)
      {
        if (angleMinFourthQuater > item)
        {
          angleMinFourthQuater = item;
        }
      }
    }

    // Compare the ray angle with
    // the max angle in the first quater
    // and the min angle in the fouth quater.
    if (angleRay <= angleMaxFirstQuater &&
        angleRay >= angleMinFourthQuater) {
      return true;
    }
  }
  else
  {
    // Find a min and max angles for the box points.
    auto result = std::minmax_element(
          std::begin(angles), std::end(angles));

    // Compare the ray angle with the min
    // and max angles for the box points.
    if (*result.first <= angleRay &&
        angleRay <= *result.second) {
      return true;
    }
  }

  return false;
}

float Ray::convertRadianToDegrees(float const & angle)
{
  return angle / Constants::PI * 180;
}

float Ray::recalculateAngle(float const & x,
                            float const & y,
                            float const & angle)
{
  float correctedAngle = 0.0f;

  // The second quarter.
  if (y > (0.0f - Constants::kEps) &&
      x < (0.0f + Constants::kEps))
  {
    correctedAngle = 180.0f - abs(angle);
  }

  // The third quarter.
  if (y < 0.0f &&
      x < (0.0f + Constants::kEps))
  {
    correctedAngle = 180.0f + abs(angle);
  }

  // The fouth quarter.
  if (y < 0.0f &&
      x > 0.0f)
  {
    correctedAngle = 360.0f - abs(angle);
  }

  return correctedAngle;
}

float Ray::checkZeroDenominator(float const & value)
{
  float tmp = value;

  if (abs(tmp) < Constants::kEps)
  {
    tmp = Constants::kEps;
  }

  return tmp;
}

void Ray::setOrigin(const Point2D & origin)
{
  m_origin = origin;
}

void Ray::setDirection(const Point2D & direction)
{
  m_direction = normalize(direction);
}

std::ostream & operator << (std::ostream & os,
                           Ray const & rhs)
{
  os << "origin: " << rhs.origin() << "; "
     << "direction: " << rhs.direction() << std::endl;
  return os;
}
<|endoftext|>


<commit_before>/* Calf DSP Library
 * RDF file generator for LADSPA plugins.
 * Copyright (C) 2007 Krzysztof Foltman
 *
 * This program 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 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>
#include <config.h>
#include <calf/giface.h>
#include <calf/modules.h>

using namespace std;
using namespace synth;

static struct option long_options[] = {
    {"help", 0, 0, 'h'},
    {"version", 0, 0, 'v'},
    {"mode", 0, 0, 'm'},
    {0,0,0,0},
};

void make_rdf()
{
    string rdf;
    rdf =
        "<?xml version='1.0' encoding='ISO-8859-1'?>\n"
        "<!DOCTYPE rdf:RDF [\n"
        "  <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n"
        "  <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>\n"
        "  <!ENTITY dc 'http://purl.org/dc/elements/1.1/'>\n"
        "  <!ENTITY ladspa 'http://ladspa.org/ontology#'>\n"
        "]>\n";

    rdf += "<rdf:RDF xmlns:rdf=\"&rdf;\" xmlns:rdfs=\"&rdfs;\" xmlns:dc=\"&dc;\" xmlns:ladspa=\"&ladspa;\">\n";

    rdf += synth::get_builtin_modules_rdf();

    rdf += "</rdf:RDF>\n";

    printf("%s\n", rdf.c_str());
}

static void add_port(string &ports, const char *symbol, const char *name, const char *direction, int pidx)
{
    stringstream ss;
    const char *ind = "        ";

    if (ports != "") ports += " , ";
    ss << "[\n";
    if (direction) ss << ind << "a lv2:" << direction << "Port ;\n";
    ss << ind << "a lv2:AudioPort ;\n";
    ss << ind << "lv2:index " << pidx << " ;\n";
    ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
    ss << ind << "lv2:name \"" << name << "\" ;\n";
    ss << "    ]";
    ports += ss.str();
}

static void add_ctl_port(string &ports, parameter_properties &pp, int pidx)
{
    stringstream ss;
    const char *ind = "        ";

    if (ports != "") ports += " , ";
    ss << "[\n";
    ss << ind << "a lv2:InputPort ;\n";
    ss << ind << "a lv2:ControlPort ;\n";
    ss << ind << "lv2:index " << pidx << " ;\n";
    ss << ind << "lv2:symbol \"" << pp.short_name << "\" ;\n";
    ss << ind << "lv2:name \"" << pp.name << "\" ;\n";
    if ((pp.flags & PF_TYPEMASK) > 0)
        ss << ind << "lv2:portProperty lv2:integer ;\n";
    ss << showpoint;
    ss << ind << "lv2:default " << pp.def_value << " ;\n";
    ss << ind << "lv2:minimum " << pp.min << " ;\n";
    ss << ind << "lv2:maximum " << pp.max << " ;\n";
    ss << "    ]";
    ports += ss.str();
}

void make_ttl()
{
    string ttl;

    ttl =
        "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n"
        "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"
        "@prefix doap: <http://usefulinc.com/ns/doap#> .\n\n";

    vector<synth::giface_plugin_info> plugins;
    synth::get_all_plugins(plugins);
    for (unsigned int i = 0; i < plugins.size(); i++) {
        synth::giface_plugin_info &pi = plugins[i];
        ttl += string("<http://calf.sourceforge.net/plugins/")
            + string(pi.info->label)
            + "> a lv2:Plugin ;\n";
        ttl += "    doap:name \""+string(pi.info->name)+"\" ;\n";
#if USE_PHAT
        ttl += "    doap:licence <http://usefulinc.com/doap/licenses/gpl> ;\n";
#else
        ttl += "    doap:licence <http://usefulinc.com/doap/licenses/lgpl> ;\n";
#endif
        if (pi.rt_capable)
            ttl += "    lv2:optionalFeature lv2:hardRtCapable ;\n";

        string ports = "";
        int pn = 0;
        const char *in_names[] = { "in_l", "in_r" };
        const char *out_names[] = { "out_l", "out_r" };
        for (int i = 0; i < pi.inputs; i++)
            add_port(ports, in_names[i], in_names[i], "Input", pn++);
        for (int i = 0; i < pi.outputs; i++)
            add_port(ports, out_names[i], out_names[i], "Output", pn++);
        for (int i = 0; i < pi.params; i++)
            add_ctl_port(ports, pi.param_props[i], pn++);
        if (!ports.empty())
            ttl += "    lv2:port " + ports + "\n";
        ttl += ".\n\n";
    }
    printf("%s\n", ttl.c_str());
}

void make_manifest()
{
    string ttl;

    ttl =
        "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n"
        "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\n";

    vector<synth::giface_plugin_info> plugins;
    synth::get_all_plugins(plugins);
    for (unsigned int i = 0; i < plugins.size(); i++)
        ttl += string("<http://calf.sourceforge.net/plugins/")
            + string(plugins[i].info->label)
            + "> a lv2:Plugin ; lv2:binary <calf.so> ; rdfs:seeAlso <calf.ttl> .\n";

    printf("%s\n", ttl.c_str());
}

int main(int argc, char *argv[])
{
    string mode = "rdf";
    while(1) {
        int option_index;
        int c = getopt_long(argc, argv, "hvm:", long_options, &option_index);
        if (c == -1)
            break;
        switch(c) {
            case 'h':
            case '?':
                printf("LADSPA RDF generator for Calf plugin pack\nSyntax: %s [--help] [--version] [--mode rdf|ttl|manifest]\n", argv[0]);
                return 0;
            case 'v':
                printf("%s\n", PACKAGE_STRING);
                return 0;
            case 'm':
                mode = optarg;
                if (mode != "rdf" && mode != "ttl" && mode != "manifest") {
                    fprintf(stderr, "calfmakerdf: Invalid mode %s\n", optarg);
                    return 1;
                }
                break;
        }
    }
    if (mode == "rdf")
        make_rdf();
    if (mode == "ttl")
        make_ttl();
    if (mode == "manifest")
        make_manifest();
    return 0;
}
<commit_msg>+ LV2: Typo fix, licence to license<commit_after>/* Calf DSP Library
 * RDF file generator for LADSPA plugins.
 * Copyright (C) 2007 Krzysztof Foltman
 *
 * This program 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 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>
#include <config.h>
#include <calf/giface.h>
#include <calf/modules.h>

using namespace std;
using namespace synth;

static struct option long_options[] = {
    {"help", 0, 0, 'h'},
    {"version", 0, 0, 'v'},
    {"mode", 0, 0, 'm'},
    {0,0,0,0},
};

void make_rdf()
{
    string rdf;
    rdf =
        "<?xml version='1.0' encoding='ISO-8859-1'?>\n"
        "<!DOCTYPE rdf:RDF [\n"
        "  <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n"
        "  <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>\n"
        "  <!ENTITY dc 'http://purl.org/dc/elements/1.1/'>\n"
        "  <!ENTITY ladspa 'http://ladspa.org/ontology#'>\n"
        "]>\n";

    rdf += "<rdf:RDF xmlns:rdf=\"&rdf;\" xmlns:rdfs=\"&rdfs;\" xmlns:dc=\"&dc;\" xmlns:ladspa=\"&ladspa;\">\n";

    rdf += synth::get_builtin_modules_rdf();

    rdf += "</rdf:RDF>\n";

    printf("%s\n", rdf.c_str());
}

static void add_port(string &ports, const char *symbol, const char *name, const char *direction, int pidx)
{
    stringstream ss;
    const char *ind = "        ";

    if (ports != "") ports += " , ";
    ss << "[\n";
    if (direction) ss << ind << "a lv2:" << direction << "Port ;\n";
    ss << ind << "a lv2:AudioPort ;\n";
    ss << ind << "lv2:index " << pidx << " ;\n";
    ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
    ss << ind << "lv2:name \"" << name << "\" ;\n";
    ss << "    ]";
    ports += ss.str();
}

static void add_ctl_port(string &ports, parameter_properties &pp, int pidx)
{
    stringstream ss;
    const char *ind = "        ";

    if (ports != "") ports += " , ";
    ss << "[\n";
    ss << ind << "a lv2:InputPort ;\n";
    ss << ind << "a lv2:ControlPort ;\n";
    ss << ind << "lv2:index " << pidx << " ;\n";
    ss << ind << "lv2:symbol \"" << pp.short_name << "\" ;\n";
    ss << ind << "lv2:name \"" << pp.name << "\" ;\n";
    if ((pp.flags & PF_TYPEMASK) > 0)
        ss << ind << "lv2:portProperty lv2:integer ;\n";
    ss << showpoint;
    ss << ind << "lv2:default " << pp.def_value << " ;\n";
    ss << ind << "lv2:minimum " << pp.min << " ;\n";
    ss << ind << "lv2:maximum " << pp.max << " ;\n";
    ss << "    ]";
    ports += ss.str();
}

void make_ttl()
{
    string ttl;

    ttl =
        "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n"
        "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"
        "@prefix doap: <http://usefulinc.com/ns/doap#> .\n\n";

    vector<synth::giface_plugin_info> plugins;
    synth::get_all_plugins(plugins);
    for (unsigned int i = 0; i < plugins.size(); i++) {
        synth::giface_plugin_info &pi = plugins[i];
        ttl += string("<http://calf.sourceforge.net/plugins/")
            + string(pi.info->label)
            + "> a lv2:Plugin ;\n";
        ttl += "    doap:name \""+string(pi.info->name)+"\" ;\n";
#if USE_PHAT
        ttl += "    doap:license <http://usefulinc.com/doap/licenses/gpl> ;\n";
#else
        ttl += "    doap:license <http://usefulinc.com/doap/licenses/lgpl> ;\n";
#endif
        if (pi.rt_capable)
            ttl += "    lv2:optionalFeature lv2:hardRtCapable ;\n";

        string ports = "";
        int pn = 0;
        const char *in_names[] = { "in_l", "in_r" };
        const char *out_names[] = { "out_l", "out_r" };
        for (int i = 0; i < pi.inputs; i++)
            add_port(ports, in_names[i], in_names[i], "Input", pn++);
        for (int i = 0; i < pi.outputs; i++)
            add_port(ports, out_names[i], out_names[i], "Output", pn++);
        for (int i = 0; i < pi.params; i++)
            add_ctl_port(ports, pi.param_props[i], pn++);
        if (!ports.empty())
            ttl += "    lv2:port " + ports + "\n";
        ttl += ".\n\n";
    }
    printf("%s\n", ttl.c_str());
}

void make_manifest()
{
    string ttl;

    ttl =
        "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n"
        "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\n";

    vector<synth::giface_plugin_info> plugins;
    synth::get_all_plugins(plugins);
    for (unsigned int i = 0; i < plugins.size(); i++)
        ttl += string("<http://calf.sourceforge.net/plugins/")
            + string(plugins[i].info->label)
            + "> a lv2:Plugin ; lv2:binary <calf.so> ; rdfs:seeAlso <calf.ttl> .\n";

    printf("%s\n", ttl.c_str());
}

int main(int argc, char *argv[])
{
    string mode = "rdf";
    while(1) {
        int option_index;
        int c = getopt_long(argc, argv, "hvm:", long_options, &option_index);
        if (c == -1)
            break;
        switch(c) {
            case 'h':
            case '?':
                printf("LADSPA RDF generator for Calf plugin pack\nSyntax: %s [--help] [--version] [--mode rdf|ttl|manifest]\n", argv[0]);
                return 0;
            case 'v':
                printf("%s\n", PACKAGE_STRING);
                return 0;
            case 'm':
                mode = optarg;
                if (mode != "rdf" && mode != "ttl" && mode != "manifest") {
                    fprintf(stderr, "calfmakerdf: Invalid mode %s\n", optarg);
                    return 1;
                }
                break;
        }
    }
    if (mode == "rdf")
        make_rdf();
    if (mode == "ttl")
        make_ttl();
    if (mode == "manifest")
        make_manifest();
    return 0;
}
<|endoftext|>