<commit_before>/*
 * (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
 * Licensed under the GNU General Public License.
 * See LICENSE for details
 */
#include <QSettings>
#include <QNetworkInterface>
#include <QMessageBox>

#include "messenger.h"

Member member_me("", QHostInfo::localHostName(), QHostAddress(QHostAddress::LocalHost).toString(), "Available");
Group group_me("");

Messenger* m = NULL;

Messenger* messenger()
{
    if(!m)
        m = new Messenger;
    return m;
}

Member me()
{
    return member_me;
}

Group myGroup()
{
    return group_me;
}

Message::Message(quint32 pNo, Member* sender, quint32 cmd, QByteArray payload)
{
    setPacketNo(pNo);
    setSender(sender);
    setCommand(cmd);
    setPayload(payload);
}

QByteArray Message::toAscii()
{
    QByteArray arr;

    arr += QByteArray::number(INT_VERSION);
    arr += ':';
    arr += QByteArray::number(packetNo());
    arr += ':';
    arr += sender()->name().toAscii();
    arr += ':';
    arr += sender()->host().toAscii();
    arr += ':';
    arr += QByteArray::number(command());
    arr += ':';
    arr += payload();

    return arr;
}

QString Message::toString()
{
    return QString(toAscii());
}

Message Message::fromAscii(QByteArray arr)
{
    QList<QByteArray> tokens = arr.split(':');

    // reconstitute payload, if payload itself contains ':'
    for(int i = 6; i < tokens.size(); i++)
        tokens[5] += ":"+tokens[i];

    quint32 pNo = tokens[1].toInt();

    Member* m = new Member;
    m->setName(QString(tokens[2])); // default name, this will be replaced when BR_ENTRY is received
    m->setHost(QString(tokens[3]));
    m->setStatus("Available");

    quint32 cmd = tokens[4].toInt();
    QByteArray py = tokens[5];

    return Message(pNo, m, cmd, py);
}

Message Message::fromString(QString s)
{
    return Message::fromAscii(s.toAscii());
}

Messenger::Messenger() : QObject()
{
    socket = NULL;
    reset();
}

void Messenger::reset()
{
    m_packetNo = 1;

    if(socket) {
        socket->close();
        delete socket;
        socket = NULL;
    }

    socket = new QUdpSocket(this);

    if(!socket->bind(UDP_PORT))
    {
        QMessageBox::critical(0, tr("Connection Error"), tr("Could not bind, perhaps port %1 is being used by another application.").arg(UDP_PORT));
        exit(1);
    }

    refreshSettings();
    connect(socket, SIGNAL(readyRead()), this, SLOT(receiveData()));
}

Message Messenger::makeMessage(quint32 command, QByteArray payload)
{
    Message msg(packetNo(), &member_me, command, payload);
    // NOTE: This is an IMPORTANT step. that's why sniffing the data will give you big command numbers
    msg.setCommand(msg.command());

    return msg;
}

bool Messenger::sendMessage(quint32 command, QByteArray payload, Member* to)
{
    return sendMessage( makeMessage(command, payload), to );
}

bool Messenger::sendMessage(Message msg, Member* to)
{
    const QByteArray data = msg.toAscii();
    return socket->writeDatagram(data, to->address(), UDP_PORT) != -1;
}

/*
 * Sends a broadcast
 * and then also multicasts to all ips stored in the Settings
 */
bool Messenger::multicast(quint32 command, QByteArray payload)
{
    QByteArray data = makeMessage(command, payload).toAscii();

    socket->writeDatagram(data, QHostAddress::Broadcast, UDP_PORT);

    QString ip;
    foreach(ip, ips())
    {
        socket->writeDatagram(data, QHostAddress(ip), UDP_PORT);
    }
}

void Messenger::receiveData()
{
    while(socket->hasPendingDatagrams())
    {
        QByteArray data;
        data.resize(socket->pendingDatagramSize());
        QHostAddress from;

        socket->readDatagram(data.data(), data.size(), &from);

        if(QNetworkInterface::allAddresses().contains(from))
        {
            continue;
        }

        data.replace('\0', QOM_HOSTLIST_SEPARATOR);

        Message msg = Message::fromAscii(data.data());

        msg.sender()->setAddress(from.toString());

        //qDebug() << "Received" << msg.toAscii() ;
        //qDebug() << "from" << msg.sender()->name() << msg.sender()->addressString();

        switch(msg.command() & QOM_COMMAND_MASK)
        {
            case QOM_ANSENTRY:
                emit msg_ansEntry(msg);
                break;

            case QOM_BR_ENTRY:
                emit msg_entry(msg);
                break;

            case QOM_BR_EXIT:
                emit msg_exit(msg);
                break;

            case QOM_SENDMSG:
                if(msg.command() & QOM_FILEATTACHOPT)
                    emit msg_fileRecvRequest(msg);
                else
                    emit msg_recvMsg(msg);
                break;

            case QOM_RECVMSG:
                emit msg_recvConfirmMsg(msg);
                break;

            case QOM_READMSG:
                emit msg_readConfirmMsg(msg);
                break;

            case QOM_GETABSENCEINFO:
                emit msg_getAbsenceInfo(msg);

            case QOM_BR_ABSENCE:
                emit msg_absence(msg);
        }
    }
}

QStringList Messenger::ips() const
{
    QSettings s;
    s.beginGroup("ips");

    QStringList ret;

    QString ipKey;
    foreach(ipKey, s.childKeys())
    {
        ret << s.value(ipKey).toString();
    }

    return ret;
}

bool Messenger::login()
{
    multicast(QOM_BR_ENTRY, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::logout()
{
    multicast(QOM_BR_EXIT, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::nickChanged()
{
    refreshSettings();
    multicast(QOM_BR_ABSENCE, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::refreshSettings()
{
    QSettings s;
    member_me.setName(s.value("nick", QString(getenv("USER"))).toString());
    group_me.setName(s.value("group").toString());
}
<commit_msg>Fetch manual IPs from IPMsg's settings<commit_after>/*
 * (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
 * Licensed under the GNU General Public License.
 * See LICENSE for details
 */
#include <QSettings>
#include <QNetworkInterface>
#include <QMessageBox>

#include "messenger.h"

Member member_me("", QHostInfo::localHostName(), QHostAddress(QHostAddress::LocalHost).toString(), "Available");
Group group_me("");

Messenger* m = NULL;

Messenger* messenger()
{
    if(!m)
        m = new Messenger;
    return m;
}

Member me()
{
    return member_me;
}

Group myGroup()
{
    return group_me;
}

Message::Message(quint32 pNo, Member* sender, quint32 cmd, QByteArray payload)
{
    setPacketNo(pNo);
    setSender(sender);
    setCommand(cmd);
    setPayload(payload);
}

QByteArray Message::toAscii()
{
    QByteArray arr;

    arr += QByteArray::number(INT_VERSION);
    arr += ':';
    arr += QByteArray::number(packetNo());
    arr += ':';
    arr += sender()->name().toAscii();
    arr += ':';
    arr += sender()->host().toAscii();
    arr += ':';
    arr += QByteArray::number(command());
    arr += ':';
    arr += payload();

    return arr;
}

QString Message::toString()
{
    return QString(toAscii());
}

Message Message::fromAscii(QByteArray arr)
{
    QList<QByteArray> tokens = arr.split(':');

    // reconstitute payload, if payload itself contains ':'
    for(int i = 6; i < tokens.size(); i++)
        tokens[5] += ":"+tokens[i];

    quint32 pNo = tokens[1].toInt();

    Member* m = new Member;
    m->setName(QString(tokens[2])); // default name, this will be replaced when BR_ENTRY is received
    m->setHost(QString(tokens[3]));
    m->setStatus("Available");

    quint32 cmd = tokens[4].toInt();
    QByteArray py = tokens[5];

    return Message(pNo, m, cmd, py);
}

Message Message::fromString(QString s)
{
    return Message::fromAscii(s.toAscii());
}

Messenger::Messenger() : QObject()
{
    socket = NULL;
    reset();
}

void Messenger::reset()
{
    m_packetNo = 1;

    if(socket) {
        socket->close();
        delete socket;
        socket = NULL;
    }

    socket = new QUdpSocket(this);

    if(!socket->bind(UDP_PORT))
    {
        QMessageBox::critical(0, tr("Connection Error"), tr("Could not bind, perhaps port %1 is being used by another application.").arg(UDP_PORT));
        exit(1);
    }

    refreshSettings();
    connect(socket, SIGNAL(readyRead()), this, SLOT(receiveData()));
}

Message Messenger::makeMessage(quint32 command, QByteArray payload)
{
    Message msg(packetNo(), &member_me, command, payload);
    // NOTE: This is an IMPORTANT step. that's why sniffing the data will give you big command numbers
    msg.setCommand(msg.command());

    return msg;
}

bool Messenger::sendMessage(quint32 command, QByteArray payload, Member* to)
{
    return sendMessage( makeMessage(command, payload), to );
}

bool Messenger::sendMessage(Message msg, Member* to)
{
    const QByteArray data = msg.toAscii();
    return socket->writeDatagram(data, to->address(), UDP_PORT) != -1;
}

/*
 * Sends a broadcast
 * and then also multicasts to all ips stored in the Settings
 */
bool Messenger::multicast(quint32 command, QByteArray payload)
{
    QByteArray data = makeMessage(command, payload).toAscii();

    socket->writeDatagram(data, QHostAddress::Broadcast, UDP_PORT);

    QString ip;
    foreach(ip, ips())
    {
        socket->writeDatagram(data, QHostAddress(ip), UDP_PORT);
    }
}

void Messenger::receiveData()
{
    while(socket->hasPendingDatagrams())
    {
        QByteArray data;
        data.resize(socket->pendingDatagramSize());
        QHostAddress from;

        socket->readDatagram(data.data(), data.size(), &from);

        if(QNetworkInterface::allAddresses().contains(from))
        {
            continue;
        }

        data.replace('\0', QOM_HOSTLIST_SEPARATOR);

        Message msg = Message::fromAscii(data.data());

        msg.sender()->setAddress(from.toString());

        //qDebug() << "Received" << msg.toAscii() ;
        //qDebug() << "from" << msg.sender()->name() << msg.sender()->addressString();

        switch(msg.command() & QOM_COMMAND_MASK)
        {
            case QOM_ANSENTRY:
                emit msg_ansEntry(msg);
                break;

            case QOM_BR_ENTRY:
                emit msg_entry(msg);
                break;

            case QOM_BR_EXIT:
                emit msg_exit(msg);
                break;

            case QOM_SENDMSG:
                if(msg.command() & QOM_FILEATTACHOPT)
                    emit msg_fileRecvRequest(msg);
                else
                    emit msg_recvMsg(msg);
                break;

            case QOM_RECVMSG:
                emit msg_recvConfirmMsg(msg);
                break;

            case QOM_READMSG:
                emit msg_readConfirmMsg(msg);
                break;

            case QOM_GETABSENCEINFO:
                emit msg_getAbsenceInfo(msg);

            case QOM_BR_ABSENCE:
                emit msg_absence(msg);
        }
    }
}

QStringList Messenger::ips() const
{
    QSettings s;
    s.beginGroup("ips");

    QStringList ret;

    QString ipKey;
    foreach(ipKey, s.childKeys()) {
        ret << s.value(ipKey).toString();
    }

    // fetch IP Messenger IPs
    QSettings ipmsg("HSTools", "IpMsgEng");
    ipmsg.beginGroup("BroadCast");
    foreach(ipKey, ipmsg.childKeys()) {
        ret << ipmsg.value(ipKey).toString();
    }

    return ret;
}

bool Messenger::login()
{
    multicast(QOM_BR_ENTRY, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::logout()
{
    multicast(QOM_BR_EXIT, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::nickChanged()
{
    refreshSettings();
    multicast(QOM_BR_ABSENCE, member_me.name().toAscii()+'\0'+group_me.name().toAscii());
}

bool Messenger::refreshSettings()
{
    QSettings s;
    member_me.setName(s.value("nick", QString(getenv("USER"))).toString());
    group_me.setName(s.value("group").toString());
}
<|endoftext|>


<commit_before>#ifndef MUDI_JSON_HPP
#define MUDI_JSON_HPP

#include <unordered_map>
#include <vector>
#include <string>

#include <utility>  // make_pair
#include <memory>   // share_ptr
#include <exception>

#define MUDI_NS_BEGIN namespace mundi {
#define MUDI_NS_END   }

#define MUDI_N_NS_BEGIN namespace mundi { namespace {
#define MUDI_N_NS_END   }}

MUDI_N_NS_BEGIN
enum class value_type
{
  array,
  object,
  string,
  number,
  boolean,
  null,
};

MUDI_N_NS_END

// exception

MUDI_NS_BEGIN

class not_supported: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Not supported operation";
  }
};

class key_not_found: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Key not found";
  }
};

MUDI_NS_END

// interface

MUDI_NS_BEGIN

class json_value
{
public:
  virtual ~json_value() noexcept;

  virtual const json_value& operator[](const std::string& key) const
  {
    throw not_supported();
  }

  virtual const json_value& operator[](unsigned int index) const
  {
    throw not_supported();
  }

  virtual bool boolean_value() const noexcept
  {
    return false;
  }

  virtual std::string string_value() const noexcept
  {
    return "null";
  }

  virtual int int_value() const noexcept
  {
    return 0;
  }

  virtual double double_value() const noexcept
  {
    return 0;
  }

  bool is_bool() const noexcept
  {
    return type() == value_type::boolean;
  }

  bool is_array() const noexcept
  {
    return type() == value_type::array;
  }

  bool is_string() const noexcept
  {
    return type() == value_type::string;
  }

  bool is_number() const noexcept
  {
    return type() == value_type::number;
  }

  bool is_object() const noexcept
  {
    return type() == value_type::object;
  }

  bool is_null() const noexcept
  {
    return type() == value_type::null;
  }

protected:
  virtual value_type type() const noexcept
  {
    return value_type::null;
  }
};

std::unique_ptr<json_value> parse_string(const std::string& str);
std::unique_ptr<json_value> parse_cstring(const char* cstr, unsigned int len);

MUDI_NS_END

// string

MUDI_N_NS_BEGIN

typedef std::shared_ptr<std::string> buffer_ptr;

class json_string: public json_value
{
public:
  json_string(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_string(const json_string& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_string& operator=(const json_string& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    auto tmp = rhs;
    std::swap(*this, tmp);
    return *this;
  }

  json_string(json_string&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_string& operator=(json_string&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  std::string string_value() const noexcept override
  {
    return buffer->substr(pos, len);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::string;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

// array

MUDI_N_NS_BEGIN

class json_array: public json_value
{
public:
  json_array() = default;

  json_array(const json_array& rhs): data{ rhs.data }
  {}

  json_array& operator=(const json_array& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    auto tmp = rhs;
    std::swap(*this, tmp);
    return *this;
  }

  json_array(json_array&& rhs)
  {
    data = std::move(rhs.data);
  }

  json_array& operator=(json_array&& rhs)
  {
    data = std::move(rhs.data);
    return *this;
  }

  ~json_array()
  {
    for (auto& v : data) {
      delete v;
    }
    data.clear();
  }

  const json_value& operator[](unsigned int index) const override
  {
    return *data.at(index);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::array;
  }

private:
  void append(json_value* val) noexcept
  {
    data.push_back(val);
  }

private:
  std::vector<json_value*> data;
};

MUDI_N_NS_END

// object

MUDI_N_NS_BEGIN

class json_object: public json_value
{
public:
  json_object() = default;

  json_object(const json_object& rhs): data{ rhs.data }
  {}

  json_object& operator=(const json_object& rhs)
  {
    data = rhs.data;
    return *this;
  }

  json_object(json_object&& rhs)
  {
    data = std::move(rhs.data);
  }

  json_object& operator=(json_object&& rhs)
  {
    data = std::move(rhs.data);
    return *this;
  }

  const json_value& operator[](const std::string& key) const override
  {
    auto found = data.find(key);
    if (found == data.cend()) {
      throw key_not_found();
    } else {
      return *(found->second);
    }
  }

  ~json_object()
  {
    for (auto& o : data) {
      delete o.second;
    }
    data.clear();
  }

  bool append(const std::string& key, json_value* value) noexcept
  {
    auto ret = data.insert(std::make_pair(key, value));
    return ret.second;
  }

  void remove(const std::string& key)
  {
    auto found = data.find(key);
    if (found != data.end())
      data.erase(found);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::object;
  }

private:
  std::unordered_map<std::string, json_value*> data;
};

MUDI_N_NS_END

// number

MUDI_N_NS_BEGIN

class json_number: public json_value
{
public:
  json_number(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_number(const json_number& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_number& operator=(const json_number& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    pos = rhs.pos;
    len = rhs.len;
    buffer = rhs.buffer;

    return *this;
  }

  json_number(json_number&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_number& operator=(json_number&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  int int_value() const noexcept override
  {
    return 0;
  }

  double double_value() const noexcept override
  {
    return 0;
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::number;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

// boolean

MUDI_N_NS_BEGIN

class json_boolean: public json_value
{
public:
  json_boolean(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_boolean(const json_boolean& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_boolean& operator=(const json_boolean& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    pos = rhs.pos;
    len = rhs.len;
    buffer = rhs.buffer;

    return *this;
  }

  json_boolean(json_boolean&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_boolean& operator=(json_boolean&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  bool boolean_value() const noexcept override
  {
    auto str = buffer->substr(pos, len);
    if (0 == str.compare("true")) {
      return true;
    } else {
      return false;
    }
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::boolean;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

#endif
<commit_msg>parser<commit_after>#ifndef MUDI_JSON_HPP
#define MUDI_JSON_HPP

#include <unordered_map>
#include <vector>
#include <string>

#include <utility>  // make_pair
#include <memory>   // share_ptr
#include <cctype>   // isspace
#include <exception>

#define MUDI_NS_BEGIN namespace mundi {
#define MUDI_NS_END   }

#define MUDI_N_NS_BEGIN namespace mundi { namespace {
#define MUDI_N_NS_END   }}

MUDI_N_NS_BEGIN
enum class value_type
{
  array,
  object,
  string,
  number,
  boolean,
  null,
};

MUDI_N_NS_END

// exception

MUDI_N_NS_BEGIN

class not_supported: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Not supported operation";
  }
};

class key_not_found: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Key not found";
  }
};

class premature_eof: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Input end prematurely";
  }
};

class unknown_input: public std::exception
{
public:
  const char* what() const noexcept override
  {
    return "Unknown input";
  }
};

MUDI_N_NS_END

// interface

MUDI_NS_BEGIN

class json_value
{
public:
  virtual ~json_value() noexcept;

  virtual const json_value& operator[](const std::string& key) const
  {
    throw not_supported();
  }

  virtual const json_value& operator[](unsigned int index) const
  {
    throw not_supported();
  }

  virtual bool boolean_value() const noexcept
  {
    return false;
  }

  virtual std::string string_value() const noexcept
  {
    return "null";
  }

  virtual int int_value() const noexcept
  {
    return 0;
  }

  virtual double double_value() const noexcept
  {
    return 0;
  }

  bool is_bool() const noexcept
  {
    return type() == value_type::boolean;
  }

  bool is_array() const noexcept
  {
    return type() == value_type::array;
  }

  bool is_string() const noexcept
  {
    return type() == value_type::string;
  }

  bool is_number() const noexcept
  {
    return type() == value_type::number;
  }

  bool is_object() const noexcept
  {
    return type() == value_type::object;
  }

  bool is_null() const noexcept
  {
    return type() == value_type::null;
  }

protected:
  virtual value_type type() const noexcept
  {
    return value_type::null;
  }
};

std::unique_ptr<json_value> parse_string(const std::string& str)
{
  json_parser p{ str };
  return p.parse();
}

std::unique_ptr<json_value> parse_cstring(const char* cstr, unsigned int len)
{
  json_parser p{cstr, len}
  return p.parse();
}

MUDI_NS_END

// string

MUDI_N_NS_BEGIN

typedef std::shared_ptr<std::string> buffer_ptr;

class json_string: public json_value
{
public:
  json_string(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_string(const json_string& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_string& operator=(const json_string& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    auto tmp = rhs;
    std::swap(*this, tmp);
    return *this;
  }

  json_string(json_string&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_string& operator=(json_string&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  std::string string_value() const noexcept override
  {
    return buffer->substr(pos, len);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::string;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

// array

MUDI_N_NS_BEGIN

class json_array: public json_value
{
public:
  json_array() = default;

  json_array(const json_array& rhs): data{ rhs.data }
  {}

  json_array& operator=(const json_array& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    auto tmp = rhs;
    std::swap(*this, tmp);
    return *this;
  }

  json_array(json_array&& rhs)
  {
    data = std::move(rhs.data);
  }

  json_array& operator=(json_array&& rhs)
  {
    data = std::move(rhs.data);
    return *this;
  }

  ~json_array()
  {
    for (auto& v : data) {
      delete v;
    }
    data.clear();
  }

  const json_value& operator[](unsigned int index) const override
  {
    return *data.at(index);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::array;
  }

private:
  void append(json_value* val) noexcept
  {
    data.push_back(val);
  }

private:
  std::vector<json_value*> data;
};

MUDI_N_NS_END

// object

MUDI_N_NS_BEGIN

class json_object: public json_value
{
public:
  json_object() = default;

  json_object(const json_object& rhs): data{ rhs.data }
  {}

  json_object& operator=(const json_object& rhs)
  {
    data = rhs.data;
    return *this;
  }

  json_object(json_object&& rhs)
  {
    data = std::move(rhs.data);
  }

  json_object& operator=(json_object&& rhs)
  {
    data = std::move(rhs.data);
    return *this;
  }

  const json_value& operator[](const std::string& key) const override
  {
    auto found = data.find(key);
    if (found == data.cend()) {
      throw key_not_found();
    } else {
      return *(found->second);
    }
  }

  ~json_object()
  {
    for (auto& o : data) {
      delete o.second;
    }
    data.clear();
  }

  bool append(const std::string& key, json_value* value) noexcept
  {
    auto ret = data.insert(std::make_pair(key, value));
    return ret.second;
  }

  void remove(const std::string& key)
  {
    auto found = data.find(key);
    if (found != data.end())
      data.erase(found);
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::object;
  }

private:
  std::unordered_map<std::string, json_value*> data;
};

MUDI_N_NS_END

// number

MUDI_N_NS_BEGIN

class json_number: public json_value
{
public:
  json_number(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_number(const json_number& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_number& operator=(const json_number& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    pos = rhs.pos;
    len = rhs.len;
    buffer = rhs.buffer;

    return *this;
  }

  json_number(json_number&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_number& operator=(json_number&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  int int_value() const noexcept override
  {
    return 0;
  }

  double double_value() const noexcept override
  {
    return 0;
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::number;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

// boolean

MUDI_N_NS_BEGIN

class json_boolean: public json_value
{
public:
  json_boolean(unsigned int pos, unsigned int len, buffer_ptr buf): pos{ pos }, len{ len }, buffer{ buf }
  {}

  json_boolean(const json_boolean& rhs): pos{ rhs.pos }, len{ rhs.len }, buffer{ rhs.buffer }
  {}

  json_boolean& operator=(const json_boolean& rhs)
  {
    if (&rhs == this) {
      return *this;
    }

    pos = rhs.pos;
    len = rhs.len;
    buffer = rhs.buffer;

    return *this;
  }

  json_boolean(json_boolean&& rhs): pos{ rhs.pos }, len{ rhs.len }
  {
    buffer = std::move(rhs.buffer);
  }

  json_boolean& operator=(json_boolean&& rhs)
  {
    pos = rhs.pos;
    len = rhs.len;
    buffer = std::move(rhs.buffer);

    return *this;
  }

  bool boolean_value() const noexcept override
  {
    auto str = buffer->substr(pos, len);
    if (0 == str.compare("true")) {
      return true;
    } else {
      return false;
    }
  }

protected:
  value_type type() const noexcept override
  {
    return value_type::boolean;
  }

private:
  unsigned int pos;
  unsigned int len;
  buffer_ptr buffer;
};

MUDI_N_NS_END

// parser

MUDI_N_NS_BEGIN

void Ensures(bool pred)
{
  assert(pred);
}

class json_parser
{
public:
  json_parser(const std::string& input): cursor{ 0 }
  {
    buffer = make_shared(input);
    end = input.length();
  }

  json_parser(const char* input, unsigned int len): cursor{ 0 }, end{ len }
  {
    buffer = make_shared(input, len);
  }

  json_parser(const json_parser&) = delete;
  json_parser& operator=(const json_parser&) = delete;

  std::unique_ptr<json_value> parse()
  {

  }

private:
  value_type get_next_value_type()
  {
    for(;;) {
      char c = peek_or_throw();
      if (isspace(c) || c == ':' || c == ',') {
        continue;
      } else if (c == '{') {
        return value_type::object;
      } else if (c == '[') {
        return value_type::array;
      } else if (c == '\"') {
        return value_type::string;
      } else if (isdigit(c)) {
        return value_type::number;
      } else if (c == '-') {
        char next = peek_or_throw(2);
        if (isdigit(next)) {
          return value_type::number;
        } else {
          throw unknown_input();
        }
      }
    }
  }

  char peek_or_throw(unsigned int delta = 1)
  {
    if (cursor + delta < end) {
      return buffer->at(cursor);
    }
    throw premature_eof();
  }

  char get_next_or_throw()
  {
    char ret = peek_or_throw();
    cursor += 1;
    return ret;
  }

  json_number parse_number();
  json_string parse_string();

private:
  unsigned int cursor;
  unsigned int end;
  buffer_ptr buffer;
};

json_number json_parser::parse_number()
{

}

json_string json_parser::pase_string()
{
  Ensures(buffer->at(cursor) == "\"");   // precondition

  cursor += 1;
  unsigned int begin = cursor;

  for (unsigned int i = cursor; i < end; ++i) {
    char c = buffer->at(i);
    if (c == "\\") {
      char next = get_next_or_throw();
      if (next == "\"") {
        continue;
      }
    }

    if (c == "\"") {
      break;
    }
  }

  Ensures(buffer->at(cursor - 1) == "\"");  // postcondition
}

MUDI_N_NS_END

#endif
<|endoftext|>


<commit_before>#include "command.hh"
#include "globals.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "names.hh"
#include "get-drvs.hh"
#include "common-args.hh"
#include "json.hh"
#include "shared.hh"
#include "eval-cache.hh"
#include "attr-path.hh"

#include <regex>
#include <fstream>

using namespace nix;

std::string wrap(std::string prefix, std::string s)
{
    return prefix + s + ANSI_NORMAL;
}

std::string hilite(const std::string & s, const std::smatch & m, std::string postfix)
{
    return
        m.empty()
        ? s
        : std::string(m.prefix())
          + ANSI_GREEN + std::string(m.str()) + postfix
          + std::string(m.suffix());
}

struct CmdSearch : InstallableCommand, MixJSON
{
    std::vector<std::string> res;

    CmdSearch()
    {
        expectArgs("regex", &res);
    }

    std::string description() override
    {
        return "query available packages";
    }

    Examples examples() override
    {
        return {
            Example{
                "To show all packages in the flake in the current directory:",
                "nix search"
            },
            Example{
                "To show packages in the 'nixpkgs' flake containing 'blender' in its name or description:",
                "nix search nixpkgs blender"
            },
            Example{
                "To search for Firefox or Chromium:",
                "nix search nixpkgs 'firefox|chromium'"
            },
            Example{
                "To search for packages containing 'git' and either 'frontend' or 'gui':",
                "nix search nixpkgs git 'frontend|gui'"
            }
        };
    }

    Strings getDefaultFlakeAttrPaths() override
    {
        return {
            "packages." + settings.thisSystem.get() + ".",
            "legacyPackages." + settings.thisSystem.get() + "."
        };
    }

    void run(ref<Store> store) override
    {
        settings.readOnlyMode = true;

        // Empty search string should match all packages
        // Use "^" here instead of ".*" due to differences in resulting highlighting
        // (see #1893 -- libc++ claims empty search string is not in POSIX grammar)
        if (res.empty())
            res.push_back("^");

        std::vector<std::regex> regexes;
        regexes.reserve(res.size());

        for (auto & re : res)
            regexes.push_back(std::regex(re, std::regex::extended | std::regex::icase));

        auto state = getEvalState();

        auto jsonOut = json ? std::make_unique<JSONObject>(std::cout) : nullptr;

        uint64_t results = 0;

        std::function<void(eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath)> visit;

        visit = [&](eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath)
        {
            Activity act(*logger, lvlInfo, actUnknown,
                fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
            try {
                auto recurse = [&]()
                {
                    for (const auto & attr : cursor.getAttrs()) {
                        auto cursor2 = cursor.getAttr(attr);
                        auto attrPath2(attrPath);
                        attrPath2.push_back(attr);
                        visit(*cursor2, attrPath2);
                    }
                };

                if (cursor.isDerivation()) {
                    size_t found = 0;

                    DrvName name(cursor.getAttr("name")->getString());

                    auto aMeta = cursor.maybeGetAttr("meta");
                    auto aDescription = aMeta ? aMeta->maybeGetAttr("description") : nullptr;
                    auto description = aDescription ? aDescription->getString() : "";
                    std::replace(description.begin(), description.end(), '\n', ' ');
                    auto attrPath2 = concatStringsSep(".", attrPath);

                    std::smatch attrPathMatch;
                    std::smatch descriptionMatch;
                    std::smatch nameMatch;

                    for (auto & regex : regexes) {
                        std::regex_search(attrPath2, attrPathMatch, regex);
                        std::regex_search(name.name, nameMatch, regex);
                        std::regex_search(description, descriptionMatch, regex);
                        if (!attrPathMatch.empty()
                            || !nameMatch.empty()
                            || !descriptionMatch.empty())
                            found++;
                    }

                    if (found == res.size()) {
                        results++;
                        if (json) {
                            auto jsonElem = jsonOut->object(attrPath2);
                            jsonElem.attr("pkgName", name.name);
                            jsonElem.attr("version", name.version);
                            jsonElem.attr("description", description);
                        } else {
                            auto name2 = hilite(name.name, nameMatch, "\e[0;2m")
                                + std::string(name.fullName, name.name.length());
                            if (results > 1) logger->stdout("");
                            logger->stdout(
                                "* %s (%s)",
                                wrap("\e[0;1m", hilite(attrPath2, attrPathMatch, "\e[0;1m")),
                                wrap("\e[0;2m", hilite(name2, nameMatch, "\e[0;2m")));
                            if (description != "")
                                logger->stdout(
                                    "  %s", hilite(description, descriptionMatch, ANSI_NORMAL));
                        }
                    }
                }

                else if (
                    attrPath.size() == 0
                    || (attrPath[0] == "legacyPackages" && attrPath.size() <= 2)
                    || (attrPath[0] == "packages" && attrPath.size() <= 2))
                    recurse();

            } catch (EvalError & e) {
                if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
                    throw;
            }
        };

        for (auto & [cursor, prefix] : installable->getCursor(*state, true))
            visit(*cursor, parseAttrPath(*state, prefix));

        if (!results)
            throw Error("no results for the given search term(s)!");
    }
};

static auto r1 = registerCommand<CmdSearch>("search");
<commit_msg>nix search: Show version<commit_after>#include "command.hh"
#include "globals.hh"
#include "eval.hh"
#include "eval-inline.hh"
#include "names.hh"
#include "get-drvs.hh"
#include "common-args.hh"
#include "json.hh"
#include "shared.hh"
#include "eval-cache.hh"
#include "attr-path.hh"

#include <regex>
#include <fstream>

using namespace nix;

std::string wrap(std::string prefix, std::string s)
{
    return prefix + s + ANSI_NORMAL;
}

std::string hilite(const std::string & s, const std::smatch & m, std::string postfix)
{
    return
        m.empty()
        ? s
        : std::string(m.prefix())
          + ANSI_GREEN + std::string(m.str()) + postfix
          + std::string(m.suffix());
}

struct CmdSearch : InstallableCommand, MixJSON
{
    std::vector<std::string> res;

    CmdSearch()
    {
        expectArgs("regex", &res);
    }

    std::string description() override
    {
        return "query available packages";
    }

    Examples examples() override
    {
        return {
            Example{
                "To show all packages in the flake in the current directory:",
                "nix search"
            },
            Example{
                "To show packages in the 'nixpkgs' flake containing 'blender' in its name or description:",
                "nix search nixpkgs blender"
            },
            Example{
                "To search for Firefox or Chromium:",
                "nix search nixpkgs 'firefox|chromium'"
            },
            Example{
                "To search for packages containing 'git' and either 'frontend' or 'gui':",
                "nix search nixpkgs git 'frontend|gui'"
            }
        };
    }

    Strings getDefaultFlakeAttrPaths() override
    {
        return {
            "packages." + settings.thisSystem.get() + ".",
            "legacyPackages." + settings.thisSystem.get() + "."
        };
    }

    void run(ref<Store> store) override
    {
        settings.readOnlyMode = true;

        // Empty search string should match all packages
        // Use "^" here instead of ".*" due to differences in resulting highlighting
        // (see #1893 -- libc++ claims empty search string is not in POSIX grammar)
        if (res.empty())
            res.push_back("^");

        std::vector<std::regex> regexes;
        regexes.reserve(res.size());

        for (auto & re : res)
            regexes.push_back(std::regex(re, std::regex::extended | std::regex::icase));

        auto state = getEvalState();

        auto jsonOut = json ? std::make_unique<JSONObject>(std::cout) : nullptr;

        uint64_t results = 0;

        std::function<void(eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath)> visit;

        visit = [&](eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath)
        {
            Activity act(*logger, lvlInfo, actUnknown,
                fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
            try {
                auto recurse = [&]()
                {
                    for (const auto & attr : cursor.getAttrs()) {
                        auto cursor2 = cursor.getAttr(attr);
                        auto attrPath2(attrPath);
                        attrPath2.push_back(attr);
                        visit(*cursor2, attrPath2);
                    }
                };

                if (cursor.isDerivation()) {
                    size_t found = 0;

                    DrvName name(cursor.getAttr("name")->getString());

                    auto aMeta = cursor.maybeGetAttr("meta");
                    auto aDescription = aMeta ? aMeta->maybeGetAttr("description") : nullptr;
                    auto description = aDescription ? aDescription->getString() : "";
                    std::replace(description.begin(), description.end(), '\n', ' ');
                    auto attrPath2 = concatStringsSep(".", attrPath);

                    std::smatch attrPathMatch;
                    std::smatch descriptionMatch;
                    std::smatch nameMatch;

                    for (auto & regex : regexes) {
                        std::regex_search(attrPath2, attrPathMatch, regex);
                        std::regex_search(name.name, nameMatch, regex);
                        std::regex_search(description, descriptionMatch, regex);
                        if (!attrPathMatch.empty()
                            || !nameMatch.empty()
                            || !descriptionMatch.empty())
                            found++;
                    }

                    if (found == res.size()) {
                        results++;
                        if (json) {
                            auto jsonElem = jsonOut->object(attrPath2);
                            jsonElem.attr("pname", name.name);
                            jsonElem.attr("version", name.version);
                            jsonElem.attr("description", description);
                        } else {
                            auto name2 = hilite(name.name, nameMatch, "\e[0;2m");
                            if (results > 1) logger->stdout("");
                            logger->stdout(
                                "* %s%s",
                                wrap("\e[0;1m", hilite(attrPath2, attrPathMatch, "\e[0;1m")),
                                name.version != "" ? " (" + name.version + ")" : "");
                            if (description != "")
                                logger->stdout(
                                    "  %s", hilite(description, descriptionMatch, ANSI_NORMAL));
                        }
                    }
                }

                else if (
                    attrPath.size() == 0
                    || (attrPath[0] == "legacyPackages" && attrPath.size() <= 2)
                    || (attrPath[0] == "packages" && attrPath.size() <= 2))
                    recurse();

            } catch (EvalError & e) {
                if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
                    throw;
            }
        };

        for (auto & [cursor, prefix] : installable->getCursor(*state, true))
            visit(*cursor, parseAttrPath(*state, prefix));

        if (!results)
            throw Error("no results for the given search term(s)!");
    }
};

static auto r1 = registerCommand<CmdSearch>("search");
<|endoftext|>


<commit_before>#include "json_v8_renderer.hpp"

// v8
#include <nan.h>

// OSRM
#include <osrm/json_container.hpp>
#include <osrm/libosrm_config.hpp>
#include <osrm/osrm.hpp>
#include <osrm/route_parameters.hpp>

// STL
#include <iostream>
#include <memory>

namespace node_osrm {

typedef std::unique_ptr<OSRM> osrm_ptr;
typedef std::unique_ptr<RouteParameters> route_parameters_ptr;
namespace {
template <class T, class... Types>
std::unique_ptr<T> make_unique(Types &&... Args)
{
    return (std::unique_ptr<T>(new T(std::forward<Types>(Args)...)));
}
}

using namespace v8;

class Engine final : public node::ObjectWrap {
public:
    static Persistent<FunctionTemplate> constructor;
    static void Initialize(Handle<Object>);
    static NAN_METHOD(New);
    static NAN_METHOD(route);
    static NAN_METHOD(locate);
    static NAN_METHOD(nearest);
    static NAN_METHOD(table);

    static void Run(_NAN_METHOD_ARGS, route_parameters_ptr);
    static void AsyncRun(uv_work_t*);
    static void AfterRun(uv_work_t*);

private:
    Engine(libosrm_config &lib_config)
        : ObjectWrap(),
          this_(make_unique<OSRM>(lib_config))
    {}

    osrm_ptr this_;
};

Persistent<FunctionTemplate> Engine::constructor;

void Engine::Initialize(Handle<Object> target) {
    NanScope();
    Local<FunctionTemplate> lcons = NanNew<FunctionTemplate>(Engine::New);
    lcons->InstanceTemplate()->SetInternalFieldCount(1);
    lcons->SetClassName(NanNew("OSRM"));
    NODE_SET_PROTOTYPE_METHOD(lcons, "route", route);
    NODE_SET_PROTOTYPE_METHOD(lcons, "locate", locate);
    NODE_SET_PROTOTYPE_METHOD(lcons, "nearest", nearest);
    NODE_SET_PROTOTYPE_METHOD(lcons, "table", table);
    target->Set(NanNew("OSRM"), lcons->GetFunction());
    NanAssignPersistent(constructor, lcons);
}

NAN_METHOD(Engine::New)
{
    NanScope();

    if (!args.IsConstructCall()) {
        NanThrowTypeError("Cannot call constructor as function, you need to use 'new' keyword");
        NanReturnUndefined();
    }

    try {
        libosrm_config lib_config;
        if (args.Length() == 1) {
            std::string base = *String::Utf8Value(args[0]->ToString());
            lib_config.server_paths["base"] = base;
            lib_config.use_shared_memory = false;
        } else if (args.Length() >= 2) {
            if (!args[1]->IsUint32()) {
                NanThrowError("the maximum number of locations in the distance table must be an unsigned integer");
                NanReturnUndefined();
            }
            lib_config.max_locations_distance_table = args[1]->ToUint32()->Value();
        }

        auto im = new Engine(lib_config);
        im->Wrap(args.This());
        NanReturnValue(args.This());
    } catch (std::exception const& ex) {
         NanThrowTypeError(ex.what());
         NanReturnUndefined();
    }
}

struct RunQueryBaton {
    uv_work_t request;
    Engine * machine;
    osrm::json::Object result;
    route_parameters_ptr params;
    Persistent<Function> cb;
    std::string error;
};

NAN_METHOD(Engine::route)
{
    NanScope();

    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    if (!args[0]->IsObject()) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined()) {
        NanThrowError("first arg must be an object");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->zoom_level = 18; //no generalization
    params->print_instructions = false; //turn by turn instructions
    params->alternate_route = true; //get an alternate route, too
    params->geometry = true; //retrieve geometry of route
    params->compression = true; //polyline encoding
    params->check_sum = 0; //see wiki
    params->service = "viaroute"; //that's routing
    params->output_format = "json";
    params->jsonp_parameter = ""; //set for jsonp wrapping
    params->language = ""; //unused atm

    if (!obj->Has(NanNew("coordinates"))) {
        NanThrowError("must provide a coordinates property");
        NanReturnUndefined();
    }

    Local<Value> coordinates = obj->Get(NanNew("coordinates"));
    if (!coordinates->IsArray()) {
        NanThrowError("coordinates must be an array of (lat/long) pairs");
        NanReturnUndefined();
    }

    Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
    if (coordinates_array->Length() < 2) {
        NanThrowError("at least two coordinates must be provided");
        NanReturnUndefined();
    }

    for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
        Local<Value> coordinate = coordinates_array->Get(i);

        if (!coordinate->IsArray()) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
        if (coordinate_pair->Length() != 2) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                         static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    }

    if (obj->Has(NanNew("alternateRoute"))) {
        params->alternate_route = obj->Get(NanNew("alternateRoute"))->BooleanValue();
    }

    if (obj->Has(NanNew("checksum"))) {
        params->check_sum = static_cast<unsigned>(obj->Get(NanNew("checksum"))->Uint32Value());
    }

    if (obj->Has(NanNew("zoomLevel"))) {
        params->zoom_level = static_cast<short>(obj->Get(NanNew("zoomLevel"))->Int32Value());
    }

    if (obj->Has(NanNew("printInstructions"))) {
        params->print_instructions = obj->Get(NanNew("printInstructions"))->BooleanValue();
    }

    if (obj->Has(NanNew("jsonpParameter"))) {
        params->jsonp_parameter = *v8::String::Utf8Value(obj->Get(NanNew("jsonpParameter")));
    }

    if (obj->Has(NanNew("hints"))) {
        Local<Value> hints = obj->Get(NanNew("hints"));

        if (!hints->IsArray()) {
            NanThrowError("hints must be an array of strings/null");
            NanReturnUndefined();
        }

        Local<Array> hints_array = Local<Array>::Cast(hints);
        for (uint32_t i = 0; i < hints_array->Length(); ++i) {
            Local<Value> hint = hints_array->Get(i);
            if (hint->IsString()) {
                params->hints.push_back(*v8::String::Utf8Value(hint));
            } else if(hint->IsNull()){
                params->hints.push_back("");
            }else{
                NanThrowError("hint must be null or string");
                NanReturnUndefined();
            }
        }
    }

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::locate)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Value> coordinate = args[0];
    if (!coordinate->IsArray()) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
    if (coordinate_pair->Length() != 2) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->service = "locate";
    params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                     static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::table)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined()) {
        NanThrowError("first arg must be an object");
        NanReturnUndefined();
    }

    Local<Value> coordinates = obj->Get(NanNew("coordinates"));
    if (!coordinates->IsArray()) {
        NanThrowError("coordinates must be an array of (lat/long) pairs");
        NanReturnUndefined();
    }

    Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
    if (coordinates_array->Length() < 2) {
        NanThrowError("at least two coordinates must be provided");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();
    params->service = "table";

    // add all coordinates
    for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
        Local<Value> coordinate = coordinates_array->Get(i);

        if (!coordinate->IsArray()) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
        if (coordinate_pair->Length() != 2) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                         static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    }

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::nearest)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Value> coordinate = args[0];
    if (!coordinate->IsArray()) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
    if (coordinate_pair->Length() != 2) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->service = "nearest";
    params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                     static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    Run(args, std::move(params));
    NanReturnUndefined();
}

void Engine::Run(_NAN_METHOD_ARGS, route_parameters_ptr params)
{
    NanScope();
    Local<Value> callback = args[args.Length()-1];

    if (!callback->IsFunction()) {
        NanThrowTypeError("last argument must be a callback function");
        return;
    }

    auto closure = new RunQueryBaton();
    closure->request.data = closure;
    closure->machine = ObjectWrap::Unwrap<Engine>(args.This());
    closure->params = std::move(params);
    closure->error = "";
    NanAssignPersistent(closure->cb, callback.As<Function>());
    uv_queue_work(uv_default_loop(), &closure->request, AsyncRun, reinterpret_cast<uv_after_work_cb>(AfterRun));
    closure->machine->Ref();
    return;
}

void Engine::AsyncRun(uv_work_t* req) {
    RunQueryBaton *closure = static_cast<RunQueryBaton *>(req->data);
    try {
        closure->machine->this_->RunQuery(*closure->params, closure->result);
    } catch(std::exception const& ex) {
        closure->error = ex.what();
    }
}

void Engine::AfterRun(uv_work_t* req) {
    NanScope();
    RunQueryBaton *closure = static_cast<RunQueryBaton *>(req->data);
    TryCatch try_catch;
    if (closure->error.size() > 0) {
        Local<Value> argv[1] = { NanError(closure->error.c_str()) };
        NanMakeCallback(NanGetCurrentContext()->Global(), NanNew(closure->cb), 1, argv);
    } else {
        Local<Value> result;
        osrm::json::render(result, closure->result);
        Local<Value> argv[2] = { NanNull(), result };
        NanMakeCallback(NanGetCurrentContext()->Global(), NanNew(closure->cb), 2, argv);
    }
    if (try_catch.HasCaught()) {
        node::FatalException(try_catch);
    }
    closure->machine->Unref();
    NanDisposePersistent(closure->cb);
    delete closure;
}

extern "C" {
    static void start(Handle<Object> target) {
        Engine::Initialize(target);
    }
}

} // namespace node_osrm

NODE_MODULE(osrm, node_osrm::start)
<commit_msg>Add interface for match service.<commit_after>#include "json_v8_renderer.hpp"

// v8
#include <nan.h>

// OSRM
#include <osrm/json_container.hpp>
#include <osrm/libosrm_config.hpp>
#include <osrm/osrm.hpp>
#include <osrm/route_parameters.hpp>

// STL
#include <iostream>
#include <memory>

namespace node_osrm {

typedef std::unique_ptr<OSRM> osrm_ptr;
typedef std::unique_ptr<RouteParameters> route_parameters_ptr;
namespace {
template <class T, class... Types>
std::unique_ptr<T> make_unique(Types &&... Args)
{
    return (std::unique_ptr<T>(new T(std::forward<Types>(Args)...)));
}
}

using namespace v8;

class Engine final : public node::ObjectWrap {
public:
    static Persistent<FunctionTemplate> constructor;
    static void Initialize(Handle<Object>);
    static NAN_METHOD(New);
    static NAN_METHOD(route);
    static NAN_METHOD(locate);
    static NAN_METHOD(nearest);
    static NAN_METHOD(table);
    static NAN_METHOD(match);

    static void Run(_NAN_METHOD_ARGS, route_parameters_ptr);
    static void AsyncRun(uv_work_t*);
    static void AfterRun(uv_work_t*);

private:
    Engine(libosrm_config &lib_config)
        : ObjectWrap(),
          this_(make_unique<OSRM>(lib_config))
    {}

    osrm_ptr this_;
};

Persistent<FunctionTemplate> Engine::constructor;

void Engine::Initialize(Handle<Object> target) {
    NanScope();
    Local<FunctionTemplate> lcons = NanNew<FunctionTemplate>(Engine::New);
    lcons->InstanceTemplate()->SetInternalFieldCount(1);
    lcons->SetClassName(NanNew("OSRM"));
    NODE_SET_PROTOTYPE_METHOD(lcons, "route", route);
    NODE_SET_PROTOTYPE_METHOD(lcons, "locate", locate);
    NODE_SET_PROTOTYPE_METHOD(lcons, "nearest", nearest);
    NODE_SET_PROTOTYPE_METHOD(lcons, "table", table);
    NODE_SET_PROTOTYPE_METHOD(lcons, "match", match);
    target->Set(NanNew("OSRM"), lcons->GetFunction());
    NanAssignPersistent(constructor, lcons);
}

NAN_METHOD(Engine::New)
{
    NanScope();

    if (!args.IsConstructCall()) {
        NanThrowTypeError("Cannot call constructor as function, you need to use 'new' keyword");
        NanReturnUndefined();
    }

    try {
        libosrm_config lib_config;
        if (args.Length() == 1) {
            std::string base = *String::Utf8Value(args[0]->ToString());
            lib_config.server_paths["base"] = base;
            lib_config.use_shared_memory = false;
        } else if (args.Length() >= 2) {
            if (!args[1]->IsUint32()) {
                NanThrowError("the maximum number of locations in the distance table must be an unsigned integer");
                NanReturnUndefined();
            }
            lib_config.max_locations_distance_table = args[1]->ToUint32()->Value();
        }

        auto im = new Engine(lib_config);
        im->Wrap(args.This());
        NanReturnValue(args.This());
    } catch (std::exception const& ex) {
         NanThrowTypeError(ex.what());
         NanReturnUndefined();
    }
}

struct RunQueryBaton {
    uv_work_t request;
    Engine * machine;
    osrm::json::Object result;
    route_parameters_ptr params;
    Persistent<Function> cb;
    std::string error;
};

NAN_METHOD(Engine::route)
{
    NanScope();

    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    if (!args[0]->IsObject()) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined()) {
        NanThrowError("first arg must be an object");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->zoom_level = 18; //no generalization
    params->print_instructions = false; //turn by turn instructions
    params->alternate_route = true; //get an alternate route, too
    params->geometry = true; //retrieve geometry of route
    params->compression = true; //polyline encoding
    params->check_sum = 0; //see wiki
    params->service = "viaroute"; //that's routing
    params->output_format = "json";
    params->jsonp_parameter = ""; //set for jsonp wrapping
    params->language = ""; //unused atm

    if (!obj->Has(NanNew("coordinates"))) {
        NanThrowError("must provide a coordinates property");
        NanReturnUndefined();
    }

    Local<Value> coordinates = obj->Get(NanNew("coordinates"));
    if (!coordinates->IsArray()) {
        NanThrowError("coordinates must be an array of (lat/long) pairs");
        NanReturnUndefined();
    }

    Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
    if (coordinates_array->Length() < 2) {
        NanThrowError("at least two coordinates must be provided");
        NanReturnUndefined();
    }

    for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
        Local<Value> coordinate = coordinates_array->Get(i);

        if (!coordinate->IsArray()) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
        if (coordinate_pair->Length() != 2) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                         static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    }

    if (obj->Has(NanNew("alternateRoute"))) {
        params->alternate_route = obj->Get(NanNew("alternateRoute"))->BooleanValue();
    }

    if (obj->Has(NanNew("checksum"))) {
        params->check_sum = static_cast<unsigned>(obj->Get(NanNew("checksum"))->Uint32Value());
    }

    if (obj->Has(NanNew("zoomLevel"))) {
        params->zoom_level = static_cast<short>(obj->Get(NanNew("zoomLevel"))->Int32Value());
    }

    if (obj->Has(NanNew("printInstructions"))) {
        params->print_instructions = obj->Get(NanNew("printInstructions"))->BooleanValue();
    }

    if (obj->Has(NanNew("jsonpParameter"))) {
        params->jsonp_parameter = *v8::String::Utf8Value(obj->Get(NanNew("jsonpParameter")));
    }

    if (obj->Has(NanNew("hints"))) {
        Local<Value> hints = obj->Get(NanNew("hints"));

        if (!hints->IsArray()) {
            NanThrowError("hints must be an array of strings/null");
            NanReturnUndefined();
        }

        Local<Array> hints_array = Local<Array>::Cast(hints);
        for (uint32_t i = 0; i < hints_array->Length(); ++i) {
            Local<Value> hint = hints_array->Get(i);
            if (hint->IsString()) {
                params->hints.push_back(*v8::String::Utf8Value(hint));
            } else if(hint->IsNull()){
                params->hints.push_back("");
            }else{
                NanThrowError("hint must be null or string");
                NanReturnUndefined();
            }
        }
    }

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::locate)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Value> coordinate = args[0];
    if (!coordinate->IsArray()) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
    if (coordinate_pair->Length() != 2) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->service = "locate";
    params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                     static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::match)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined()) {
        NanThrowError("first arg must be an object");
        NanReturnUndefined();
    }

    Local<Value> coordinates = obj->Get(NanNew("coordinates"));
    if (!coordinates->IsArray()) {
        NanThrowError("coordinates must be an array of (lat/long) pairs");
        NanReturnUndefined();
    }

    Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
    if (coordinates_array->Length() < 2) {
        NanThrowError("at least two coordinates must be provided");
        NanReturnUndefined();
    }

    Local<Value> timestamps = obj->Get(NanNew("timestamps"));
    if (!coordinates->IsArray() && !timestamps->IsUndefined()) {
        NanThrowError("timestamps must be an array of integers (or undefined)");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();
    params->service = "match";

    if (timestamps->IsArray()) {
        Local<Array> timestamps_array = Local<Array>::Cast(timestamps);
        if (coordinates_array->Length() != timestamps_array->Length()) {
            NanThrowError("timestamp array must have the same size as the coordinates array");
            NanReturnUndefined();
        }

        // add all timestamps
        for (uint32_t i = 0; i < timestamps_array->Length(); ++i) {
            params->timestamps.emplace_back(static_cast<unsigned>(timestamps_array->Get(i)->NumberValue()));
        }
    }

    // add all coordinates
    for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
        Local<Value> coordinate = coordinates_array->Get(i);

        if (!coordinate->IsArray()) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
        if (coordinate_pair->Length() != 2) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                         static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));

    }

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::table)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined()) {
        NanThrowError("first arg must be an object");
        NanReturnUndefined();
    }

    Local<Value> coordinates = obj->Get(NanNew("coordinates"));
    if (!coordinates->IsArray()) {
        NanThrowError("coordinates must be an array of (lat/long) pairs");
        NanReturnUndefined();
    }

    Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
    if (coordinates_array->Length() < 2) {
        NanThrowError("at least two coordinates must be provided");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();
    params->service = "table";

    // add all coordinates
    for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
        Local<Value> coordinate = coordinates_array->Get(i);

        if (!coordinate->IsArray()) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
        if (coordinate_pair->Length() != 2) {
            NanThrowError("coordinates must be an array of (lat/long) pairs");
            NanReturnUndefined();
        }

        params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                         static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    }

    Run(args, std::move(params));
    NanReturnUndefined();
}

NAN_METHOD(Engine::nearest)
{
    NanScope();
    if (args.Length() < 2) {
        NanThrowTypeError("two arguments required");
        NanReturnUndefined();
    }

    Local<Value> coordinate = args[0];
    if (!coordinate->IsArray()) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    Local<Array> coordinate_pair = Local<Array>::Cast(coordinate);
    if (coordinate_pair->Length() != 2) {
        NanThrowError("first argument must be an array of lat, long");
        NanReturnUndefined();
    }

    route_parameters_ptr params = make_unique<RouteParameters>();

    params->service = "nearest";
    params->coordinates.emplace_back(static_cast<int>(coordinate_pair->Get(0)->NumberValue()*COORDINATE_PRECISION),
                                     static_cast<int>(coordinate_pair->Get(1)->NumberValue()*COORDINATE_PRECISION));
    Run(args, std::move(params));
    NanReturnUndefined();
}

void Engine::Run(_NAN_METHOD_ARGS, route_parameters_ptr params)
{
    NanScope();
    Local<Value> callback = args[args.Length()-1];

    if (!callback->IsFunction()) {
        NanThrowTypeError("last argument must be a callback function");
        return;
    }

    auto closure = new RunQueryBaton();
    closure->request.data = closure;
    closure->machine = ObjectWrap::Unwrap<Engine>(args.This());
    closure->params = std::move(params);
    closure->error = "";
    NanAssignPersistent(closure->cb, callback.As<Function>());
    uv_queue_work(uv_default_loop(), &closure->request, AsyncRun, reinterpret_cast<uv_after_work_cb>(AfterRun));
    closure->machine->Ref();
    return;
}

void Engine::AsyncRun(uv_work_t* req) {
    RunQueryBaton *closure = static_cast<RunQueryBaton *>(req->data);
    try {
        closure->machine->this_->RunQuery(*closure->params, closure->result);
    } catch(std::exception const& ex) {
        closure->error = ex.what();
    }
}

void Engine::AfterRun(uv_work_t* req) {
    NanScope();
    RunQueryBaton *closure = static_cast<RunQueryBaton *>(req->data);
    TryCatch try_catch;
    if (closure->error.size() > 0) {
        Local<Value> argv[1] = { NanError(closure->error.c_str()) };
        NanMakeCallback(NanGetCurrentContext()->Global(), NanNew(closure->cb), 1, argv);
    } else {
        Local<Value> result;
        osrm::json::render(result, closure->result);
        Local<Value> argv[2] = { NanNull(), result };
        NanMakeCallback(NanGetCurrentContext()->Global(), NanNew(closure->cb), 2, argv);
    }
    if (try_catch.HasCaught()) {
        node::FatalException(try_catch);
    }
    closure->machine->Unref();
    NanDisposePersistent(closure->cb);
    delete closure;
}

extern "C" {
    static void start(Handle<Object> target) {
        Engine::Initialize(target);
    }
}

} // namespace node_osrm

NODE_MODULE(osrm, node_osrm::start)
<|endoftext|>


<commit_before>// Copyright (c) 2018 alex v
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "init.h"
#include "ntpclient.h"
#include "random.h"
#include "timedata.h"
#include "util.h"

#include <sstream>
#include <iomanip>

using namespace boost;
using namespace boost::asio;

bool CNtpClient::getTimestamp(uint64_t &timeRecv)
{

    io_service io_service;

    LogPrint("ntp", "[NTP] Opening socket to NTP server %s.\n", sHostName);
    try
    {

        ip::udp::resolver resolver(io_service);
        ip::udp::resolver::query query(boost::asio::ip::udp::v4(), sHostName, "ntp");

        ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);

        ip::udp::socket socket(io_service);
        socket.open(ip::udp::v4());

        boost::array<unsigned char, 48> sendBuf = {{010,0,0,0,0,0,0,0,0}};

        socket.send_to(boost::asio::buffer(sendBuf), receiver_endpoint);

        boost::array<uint32_t, 1024> recvBuf;
        ip::udp::endpoint sender_endpoint;

        try
        {

            fd_set fileDescriptorSet;
            struct timeval timeStruct;

            timeStruct.tv_sec = GetArg("-ntptimeout", DEFAULT_NTP_TIMEOUT);
            timeStruct.tv_usec = 0;
            FD_ZERO(&fileDescriptorSet);

            int nativeSocket = socket.native();

            FD_SET(nativeSocket,&fileDescriptorSet);

            select(nativeSocket+1,&fileDescriptorSet,NULL,NULL,&timeStruct);

            if(!FD_ISSET(nativeSocket,&fileDescriptorSet))
            {

                LogPrint("ntp", "[NTP] Could not read socket from NTP server %s (Read timeout)\n", sHostName);

            }
            else
            {

                socket.receive_from(boost::asio::buffer(recvBuf), sender_endpoint);

                timeRecv = ntohl((uint32_t)recvBuf[8]);

                if(timeRecv > 2208988800U) // Sanity check
                {

                    timeRecv-= 2208988800U;  // Substract 01/01/1970 == 2208988800U
                    LogPrint("ntp", "[NTP] Received timestamp: %ll\n", (uint64_t)timeRecv);

                    return true;

                }
                else
                {

                    LogPrintf("[NTP] Received wrong clock from NTP server %s (bad timestamp format)\n", sHostName);

                }

            }

        }
        catch (std::exception& e)
        {

             LogPrintf("[NTP] Could not read clock from NTP server %s (%s)\n", sHostName, e.what());

        }

    }
    catch (std::exception& e)
    {

        LogPrintf("[NTP] Could not open socket to NTP server %s (%s)\n", sHostName, e.what());

    }

    return false;
}

bool NtpClockSync()
{
    LogPrintf("[NTP] Starting clock sync...\n");

    std::vector<std::string> vNtpServers;
    std::vector<int64_t> vResults;

    if (mapMultiArgs["-ntpserver"].size() > 0)
    {
        vNtpServers = mapMultiArgs["-ntpserver"];
    }
    else
    {
        vNtpServers = vDefaultNtpServers;
    }

    string sReport = "";
    string sPrevServer = "";
    int64_t nPrevMeasure = -1;

    random_shuffle(vNtpServers.begin(), vNtpServers.end(), GetRandInt);

    unsigned int nMeasureCount = 0;

    for(unsigned int i = 0; i < vNtpServers.size(); i++)
    {
        string s = vNtpServers[i];
        CNtpClient ntpClient(s);
        uint64_t nTimestamp = 0;

        if (ShutdownRequested())
            return false;

        if(ntpClient.getTimestamp(nTimestamp))
        {
            int64_t nClockDrift = GetTimeNow() - nTimestamp;
            nMeasureCount++;

            // We push if its the first entry
            if(nMeasureCount == 1)
            {
                vResults.push_back(nClockDrift);

                string sign = "";
                if(nClockDrift > 0)
                    sign = "+";

                sReport += s + "[" + sign + to_string(nClockDrift) + "sec.] ";
            }
            // or if n.measure is odd, including prev measure too
            else if (nMeasureCount % 2 == 1)
            {
                vResults.push_back(nClockDrift);

                string sign = "";
                if(nClockDrift > 0)
                    sign = "+";

                sReport += s + "[" + sign + to_string(nClockDrift) + "sec.] ";

                vResults.push_back(nPrevMeasure);

                sign = "";
                if(nPrevMeasure > 0)
                    sign = "+";

                sReport += sPrevServer + "[" + sign + to_string(nPrevMeasure) + "sec.] ";
            }
            else
            {
                nPrevMeasure = nClockDrift;
                sPrevServer = s;
            }

            if (vResults.size() >= 5)
                break;
        }
    }

    assert(vResults.size() % 2 == 1 || vResults.size() == 0);

    unsigned int nMin = GetArg("-ntpminmeasures", MINIMUM_NTP_MEASURE);

    if (vResults.size() >= nMin)
    {
        LogPrintf("[NTP] Measured: %s\n", sReport);

        static CMedianFilter<int64_t> vNtpTimeOffsets(vResults.size(), 0);

        for(unsigned int i = 0; i < vResults.size(); i++)
        {
            vNtpTimeOffsets.input(vResults[i]);
        }

        SetNtpTimeOffset(vNtpTimeOffsets.median());

        LogPrintf("[NTP] Calculated offset from median: %d\n", GetNtpTimeOffset());
        return true;
    }
    else
    {
        return false;
    }
}
<commit_msg>Use native_handle instead of native on sockets<commit_after>// Copyright (c) 2018 alex v
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "init.h"
#include "ntpclient.h"
#include "random.h"
#include "timedata.h"
#include "util.h"

#include <sstream>
#include <iomanip>

using namespace boost;
using namespace boost::asio;

bool CNtpClient::getTimestamp(uint64_t &timeRecv)
{

    io_service io_service;

    LogPrint("ntp", "[NTP] Opening socket to NTP server %s.\n", sHostName);
    try
    {

        ip::udp::resolver resolver(io_service);
        ip::udp::resolver::query query(boost::asio::ip::udp::v4(), sHostName, "ntp");

        ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);

        ip::udp::socket socket(io_service);
        socket.open(ip::udp::v4());

        boost::array<unsigned char, 48> sendBuf = {{010,0,0,0,0,0,0,0,0}};

        socket.send_to(boost::asio::buffer(sendBuf), receiver_endpoint);

        boost::array<uint32_t, 1024> recvBuf;
        ip::udp::endpoint sender_endpoint;

        try
        {

            fd_set fileDescriptorSet;
            struct timeval timeStruct;

            timeStruct.tv_sec = GetArg("-ntptimeout", DEFAULT_NTP_TIMEOUT);
            timeStruct.tv_usec = 0;
            FD_ZERO(&fileDescriptorSet);

            int nativeSocket = socket.native_handle();

            FD_SET(nativeSocket,&fileDescriptorSet);

            select(nativeSocket+1,&fileDescriptorSet,NULL,NULL,&timeStruct);

            if(!FD_ISSET(nativeSocket,&fileDescriptorSet))
            {

                LogPrint("ntp", "[NTP] Could not read socket from NTP server %s (Read timeout)\n", sHostName);

            }
            else
            {

                socket.receive_from(boost::asio::buffer(recvBuf), sender_endpoint);

                timeRecv = ntohl((uint32_t)recvBuf[8]);

                if(timeRecv > 2208988800U) // Sanity check
                {

                    timeRecv-= 2208988800U;  // Substract 01/01/1970 == 2208988800U
                    LogPrint("ntp", "[NTP] Received timestamp: %ll\n", (uint64_t)timeRecv);

                    return true;

                }
                else
                {

                    LogPrintf("[NTP] Received wrong clock from NTP server %s (bad timestamp format)\n", sHostName);

                }

            }

        }
        catch (std::exception& e)
        {

             LogPrintf("[NTP] Could not read clock from NTP server %s (%s)\n", sHostName, e.what());

        }

    }
    catch (std::exception& e)
    {

        LogPrintf("[NTP] Could not open socket to NTP server %s (%s)\n", sHostName, e.what());

    }

    return false;
}

bool NtpClockSync()
{
    LogPrintf("[NTP] Starting clock sync...\n");

    std::vector<std::string> vNtpServers;
    std::vector<int64_t> vResults;

    if (mapMultiArgs["-ntpserver"].size() > 0)
    {
        vNtpServers = mapMultiArgs["-ntpserver"];
    }
    else
    {
        vNtpServers = vDefaultNtpServers;
    }

    string sReport = "";
    string sPrevServer = "";
    int64_t nPrevMeasure = -1;

    random_shuffle(vNtpServers.begin(), vNtpServers.end(), GetRandInt);

    unsigned int nMeasureCount = 0;

    for(unsigned int i = 0; i < vNtpServers.size(); i++)
    {
        string s = vNtpServers[i];
        CNtpClient ntpClient(s);
        uint64_t nTimestamp = 0;

        if (ShutdownRequested())
            return false;

        if(ntpClient.getTimestamp(nTimestamp))
        {
            int64_t nClockDrift = GetTimeNow() - nTimestamp;
            nMeasureCount++;

            // We push if its the first entry
            if(nMeasureCount == 1)
            {
                vResults.push_back(nClockDrift);

                string sign = "";
                if(nClockDrift > 0)
                    sign = "+";

                sReport += s + "[" + sign + to_string(nClockDrift) + "sec.] ";
            }
            // or if n.measure is odd, including prev measure too
            else if (nMeasureCount % 2 == 1)
            {
                vResults.push_back(nClockDrift);

                string sign = "";
                if(nClockDrift > 0)
                    sign = "+";

                sReport += s + "[" + sign + to_string(nClockDrift) + "sec.] ";

                vResults.push_back(nPrevMeasure);

                sign = "";
                if(nPrevMeasure > 0)
                    sign = "+";

                sReport += sPrevServer + "[" + sign + to_string(nPrevMeasure) + "sec.] ";
            }
            else
            {
                nPrevMeasure = nClockDrift;
                sPrevServer = s;
            }

            if (vResults.size() >= 5)
                break;
        }
    }

    assert(vResults.size() % 2 == 1 || vResults.size() == 0);

    unsigned int nMin = GetArg("-ntpminmeasures", MINIMUM_NTP_MEASURE);

    if (vResults.size() >= nMin)
    {
        LogPrintf("[NTP] Measured: %s\n", sReport);

        static CMedianFilter<int64_t> vNtpTimeOffsets(vResults.size(), 0);

        for(unsigned int i = 0; i < vResults.size(); i++)
        {
            vNtpTimeOffsets.input(vResults[i]);
        }

        SetNtpTimeOffset(vNtpTimeOffsets.median());

        LogPrintf("[NTP] Calculated offset from median: %d\n", GetNtpTimeOffset());
        return true;
    }
    else
    {
        return false;
    }
}
<|endoftext|>


<commit_before>/*
 *  jsreader.cpp
 *  glia
 *
 *  Created by Deniz Kural on 8/1/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "jsreader.h"

using namespace std;

int json_example(vector<sn*> &nlist) {

	map<string, sn*> node_lookup;
	//node_lookup["n1"] = *sn;

	//cout << "Starting JSON Example" << endl;
	Json::Value root;   // will contains the root value after parsing.
	Json::Reader dagreader;
	Json::StyledWriter dagwriter;

	cout << "Loading JSON file" << endl;
	ifstream input_json_file("/Users/kural/indel.json");

	bool parsingSuccessful = dagreader.parse( input_json_file, root );

	if ( !parsingSuccessful ) {

		// report to the user the failure and their locations in the document.
		cout << "Failed to parse configuration\n"
			 << dagreader.getFormattedErrorMessages();

		return 0;
	}

	// example: retrieve string:string pair
	//string encoding = dagroot.get("encoding", "UTF-8" ).asString();

	const Json::Value dag = root["dag"];

	for ( int index = 0; index < dag.size(); ++index ) {

		Json::Value node = dag[index];

		sn* cnode;
		cnode = new sn;

		cnode->name = node.get("id","NA").asString();
		cnode->sequence = node.get("sequence","").asString();
		cnode->seq_len = cnode->sequence.length();
		cnode->depth = node.get("depth",-1).asInt();

		// add to the lookup table
		node_lookup[cnode->name] = cnode;
		nlist.push_back(cnode);

	}

	for ( int index = 0; index < dag.size(); ++index ) {

		Json::Value node = dag[index];

		Json::Value p3 = node["p3"];
		for (int j = 0; j < p3.size(); ++j ) {
			//cout << p3.get(j,"NA").asString() << endl;
			nlist[index]->p3.push_back(node_lookup[p3.get(j,"NA").asString()]);
		}

		Json::Value p5 = node["p5"];
		for (int j = 0; j < p5.size(); ++j ) {
			//cout << p5.get(j,"NA").asString() << endl;
			nlist[index]->p5.push_back(node_lookup[p5.get(j,"NA").asString()]);
		}

	}

	cout << dag;
	return 0;
}

		//loadPlugIn( plugins[index].asString() );

	//setIndentLength( root["indent"].get("length", 3).asInt() );
	//setIndentUseSpace( root["indent"].get("use_space", true).asBool() );

	// ...
	// At application shutdown to make the new configuration document:
	// Since Json::Value has implicit constructor for all value types, it is not
	// necessary to explicitly construct the Json::Value object:

	//root["encoding"] = getCurrentEncoding();
	//root["indent"]["length"] = getCurrentIndentLength();
	//root["indent"]["use_space"] = getCurrentIndentUseSpace();

	// Make a new JSON document for the configuration. Preserve original comments.
	//string outputConfig = dagwriter.write( root );

	// You can also use streams.  This will put the contents of any JSON
	// stream at a particular sub-value, if you'd like.
	//cin >> dagroot["subtree"];

	// And you can write to a stream, using the StyledWriter automatically.
	//cout << root;

    //return 0;

<commit_msg>delete json fwd<commit_after>/*
 *  jsreader.cpp
 *  glia
 *
 *  Created by Deniz Kural on 8/1/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "jsreader.h"

using namespace std;

int json_example(vector<sn*> &nlist) {

	map<string, sn*> node_lookup;
	//node_lookup["n1"] = *sn;

	//cout << "Starting JSON Example" << endl;
	Json::Value root;   // will contains the root value after parsing.
	Json::Reader dagreader;
	Json::StyledWriter dagwriter;

	cout << "Loading JSON file" << endl;
	ifstream input_json_file("/Users/kural/indel.json");

	bool parsingSuccessful = dagreader.parse( input_json_file, root );

	if ( !parsingSuccessful ) {

		// report to the user the failure and their locations in the document.
		cout << "Failed to parse configuration\n"
			 << dagreader.getFormattedErrorMessages();

		return 0;
	}

	// example: retrieve string:string pair
	//string encoding = dagroot.get("encoding", "UTF-8" ).asString();

	const Json::Value dag = root["dag"];

	for ( int index = 0; index < dag.size(); ++index ) {

		Json::Value node = dag[index];

		sn* cnode;
		cnode = new sn;

		cnode->name = node.get("id","NA").asString();
		cnode->sequence = node.get("sequence","").asString();
		cnode->seq_len = cnode->sequence.length();
		cnode->depth = node.get("depth",-1).asInt();

		// add to the lookup table
		node_lookup[cnode->name] = cnode;
		nlist.push_back(cnode);

	}

	for ( int index = 0; index < dag.size(); ++index ) {

		Json::Value node = dag[index];

		Json::Value p3 = node["p3"];
		for (int j = 0; j < p3.size(); ++j ) {
			//cout << p3.get(j,"NA").asString() << endl;
			nlist[index]->p3.push_back(node_lookup[p3.get(j,"NA").asString()]);
		}

		Json::Value p5 = node["p5"];
		for (int j = 0; j < p5.size(); ++j ) {
			//cout << p5.get(j,"NA").asString() << endl;
			nlist[index]->p5.push_back(node_lookup[p5.get(j,"NA").asString()]);
		}

	}

	cout << dag;
	return 0;
}

    //loadPlugIn( plugins[index].asString() );

	//setIndentLength( root["indent"].get("length", 3).asInt() );
	//setIndentUseSpace( root["indent"].get("use_space", true).asBool() );

	// ...
	// At application shutdown to make the new configuration document:
	// Since Json::Value has implicit constructor for all value types, it is not
	// necessary to explicitly construct the Json::Value object:

	//root["encoding"] = getCurrentEncoding();
	//root["indent"]["length"] = getCurrentIndentLength();
	//root["indent"]["use_space"] = getCurrentIndentUseSpace();

	// Make a new JSON document for the configuration. Preserve original comments.
	//string outputConfig = dagwriter.write( root );

	// You can also use streams.  This will put the contents of any JSON
	// stream at a particular sub-value, if you'd like.
	//cin >> dagroot["subtree"];

	// And you can write to a stream, using the StyledWriter automatically.
	//cout << root;

    //return 0;

<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	ルネサス RX ペリフェラル／デバイス選択
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/byte_order.h"
#include "common/vect.h"
#include "common/delay.hpp"
#include "common/device.hpp"

#if defined(SIG_RX621) || defined(SIG_RX62N)
#include "RX62x/lvd.hpp"
#include "RX62x/bus.hpp"
#include "RX62x/system.hpp"
#include "RX62x/system_io.hpp"
#include "RX600/dmac.hpp"
#include "RX600/exdmac.hpp"
#include "RX62x/port.hpp"
#include "RX62x/mtu2.hpp"
#include "RX62x/poe2.hpp"
#include "RX600/ppg.hpp"
// RTC
#include "RX62x/wdt.hpp"
#include "RX600/etherc.hpp"
#include "RX600/edmac.hpp"
// USB
#include "RX600/crc.hpp"
#include "RX600/can.hpp"
#include "RX62x/s12ad.hpp"
#include "RX62x/ad.hpp"
#include "RX62x/da.hpp"
#include "RX62x/flash.hpp"

#elif defined(SIG_RX24T)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX24T/system.hpp"
#include "RX24T/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/gpt.hpp"
#include "RX24T/s12ad.hpp"
#include "RX24T/adc_in.hpp"
#include "RX24T/da.hpp"
#include "RX600/cmpc.hpp"
#include "RX24T/flash.hpp"
#include "RX24T/flash_io.hpp"
#include "RX24T/dac_out.hpp"
#include "RX600/crc.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX64M) || defined(SIG_RX71M)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/gpt.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/can.hpp"
#include "RX600/qspi.hpp"
#include "RX600/s12adc.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/eptpc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/usb.hpp"
#include "RX600/usba.hpp"
#include "RX600/scif.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/ssi.hpp"
#include "RX600/src.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#include "RX600/standby_ram.hpp"
#include "RX600/ssi_io.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crc.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX65N)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/qspi.hpp"
#include "RX600/can.hpp"
#include "RX600/s12adf.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/usb.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/sdsi.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#include "RX600/standby_ram.hpp"
#include "RX600/glcdc.hpp"
#include "RX600/glcdc_mgr.hpp"
#include "RX600/drw2d.hpp"
#include "RX600/drw2d_mgr.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX72M) || defined(SIG_RX72N)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/ppg.hpp"
#include "RX600/gptw.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/can.hpp"
#include "RX600/qspi.hpp"
#include "RX600/s12adf.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/eptpc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/pmgi.hpp"
#include "RX600/usb.hpp"
#include "RX600/scif.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/ssie.hpp"
#include "RX600/ssie_io.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#if defined(SIG_RX72M)
#include "RX600/dsmif.hpp"
#endif
#include "RX600/standby_ram.hpp"

#include "RX600/glcdc.hpp"
#include "RX600/glcdc_mgr.hpp"
#include "RX600/drw2d.hpp"
#include "RX600/drw2d_mgr.hpp"

#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX66T) || defined(SIG_RX72T)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/mpc.hpp"
#include "RX600/gptw.hpp"
#include "RX600/hrpwm.hpp"
#include "RX600/poeg.hpp"
#include "RX600/can.hpp"
#include "RX72T/s12adh.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/usb.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/cmpc.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#else
#  error "renesas.hpp: Requires SIG_RXxxx to be defined"
#endif

// RX マイコン共通ペリフェラル
#include "RX600/dtc.hpp"
#include "RX600/tmr.hpp"
#include "RX600/cmt.hpp"
#include "RX600/iwdt.hpp"
#include "RX600/sci.hpp"
#include "RX600/riic.hpp"
#include "RX600/rspi.hpp"
#include "RX600/mpu.hpp"
<commit_msg>Update: add include apth for RX62N<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	ルネサス RX ペリフェラル／デバイス選択
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/byte_order.h"
#include "common/vect.h"
#include "common/delay.hpp"
#include "common/device.hpp"

#if defined(SIG_RX621) || defined(SIG_RX62N)
#include "RX62x/lvd.hpp"
#include "RX62x/bus.hpp"
#include "RX62x/system.hpp"
#include "RX62x/system_io.hpp"
#include "RX600/dmac.hpp"
#include "RX600/exdmac.hpp"
#include "RX62x/port.hpp"
#include "RX62x/mtu2.hpp"
#include "RX62x/poe2.hpp"
#include "RX600/ppg.hpp"
// RTC
#include "RX62x/wdt.hpp"
#include "RX600/etherc.hpp"
#include "RX600/edmac.hpp"
// USB
#include "RX600/crc.hpp"
#include "RX600/can.hpp"
#include "RX62x/s12ad.hpp"
#include "RX62x/ad.hpp"
#include "RX62x/da.hpp"
#include "RX62x/flash.hpp"
#include "RX62x/flash_io.hpp"

#elif defined(SIG_RX24T)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX24T/system.hpp"
#include "RX24T/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/gpt.hpp"
#include "RX24T/s12ad.hpp"
#include "RX24T/adc_in.hpp"
#include "RX24T/da.hpp"
#include "RX600/cmpc.hpp"
#include "RX24T/flash.hpp"
#include "RX24T/flash_io.hpp"
#include "RX24T/dac_out.hpp"
#include "RX600/crc.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX64M) || defined(SIG_RX71M)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/gpt.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/can.hpp"
#include "RX600/qspi.hpp"
#include "RX600/s12adc.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/eptpc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/usb.hpp"
#include "RX600/usba.hpp"
#include "RX600/scif.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/ssi.hpp"
#include "RX600/src.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#include "RX600/standby_ram.hpp"
#include "RX600/ssi_io.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crc.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX65N)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/qspi.hpp"
#include "RX600/can.hpp"
#include "RX600/s12adf.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/usb.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/sdsi.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#include "RX600/standby_ram.hpp"
#include "RX600/glcdc.hpp"
#include "RX600/glcdc_mgr.hpp"
#include "RX600/drw2d.hpp"
#include "RX600/drw2d_mgr.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX72M) || defined(SIG_RX72N)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/exdmac.hpp"
#include "RX600/mpc.hpp"
#include "RX600/tpu.hpp"
#include "RX600/ppg.hpp"
#include "RX600/gptw.hpp"
#include "RX600/ppg.hpp"
#include "RX600/cmtw.hpp"
#include "RX600/can.hpp"
#include "RX600/qspi.hpp"
#include "RX600/s12adf.hpp"
#include "RX600/adc_in.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/sdram.hpp"
#include "RX600/etherc.hpp"
#include "RX600/eptpc.hpp"
#include "RX600/edmac.hpp"
#include "RX600/pmgi.hpp"
#include "RX600/usb.hpp"
#include "RX600/scif.hpp"
#include "RX600/rtc.hpp"
#include "RX600/rtc_io.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/ether_io.hpp"
#include "RX600/ssie.hpp"
#include "RX600/ssie_io.hpp"
#include "RX600/sdhi.hpp"
#include "RX600/sdhi_io.hpp"
#include "RX600/mmcif.hpp"
#include "RX600/pdc.hpp"
#if defined(SIG_RX72M)
#include "RX600/dsmif.hpp"
#endif
#include "RX600/standby_ram.hpp"

#include "RX600/glcdc.hpp"
#include "RX600/glcdc_mgr.hpp"
#include "RX600/drw2d.hpp"
#include "RX600/drw2d_mgr.hpp"

#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#elif defined(SIG_RX66T) || defined(SIG_RX72T)
#include "RX600/lvda.hpp"
#include "RX600/bus.hpp"

#include "RX600/system.hpp"
#include "RX600/system_io.hpp"
#include "RX600/cac.hpp"
#include "RX600/port.hpp"
#include "RX600/mtu3.hpp"
#include "RX600/poe3.hpp"
#include "RX600/dmac.hpp"
#include "RX600/elc.hpp"
#include "RX600/mpc.hpp"
#include "RX600/gptw.hpp"
#include "RX600/hrpwm.hpp"
#include "RX600/poeg.hpp"
#include "RX600/can.hpp"
#include "RX72T/s12adh.hpp"
#include "RX600/r12da.hpp"
#include "RX600/dac_out.hpp"
#include "RX600/usb.hpp"
#include "RX600/wdta.hpp"
#include "RX600/flash.hpp"
#include "RX600/flash_io.hpp"
#include "RX600/cmpc.hpp"
#include "RX600/dmac_mgr.hpp"
#include "RX600/crca.hpp"
#include "RX600/doc.hpp"

#else
#  error "renesas.hpp: Requires SIG_RXxxx to be defined"
#endif

// RX マイコン共通ペリフェラル
#include "RX600/dtc.hpp"
#include "RX600/tmr.hpp"
#include "RX600/cmt.hpp"
#include "RX600/iwdt.hpp"
#include "RX600/sci.hpp"
#include "RX600/riic.hpp"
#include "RX600/rspi.hpp"
#include "RX600/mpu.hpp"
<|endoftext|>