<commit_before>/*
 * fetch-cats.cc
 *
 * Fetch everything; needed for generation.
 *
 * Copyright (c) 2022 Linas Vepstas <linasvepstas@gmail.com>
 */
#ifdef HAVE_ATOMESE

extern "C" {
#include "../link-includes.h"            // For Dictionary
#include "../dict-common/dict-common.h"  // for Dictionary_s
#include "lookup-atomese.h"
};

#include "local-as.h"
#include <opencog/nlp/types/atom_types.h>

using namespace opencog;

void as_add_categories(Dictionary dict)
{
	Local* local = (Local*) (dict->as_server);

	// Get all sections.
	if (local->stnp)
	{
		local->stnp->fetch_all_atoms_of_type(SECTION);
		local->stnp->barrier();
	}

	// Assume one category per word and word-class.
	// (i.e. that all words will have sections)
	size_t nclasses = local->asp->get_num_atoms_of_type(WORD_CLASS_NODE);
	size_t nwords = local->asp->get_num_atoms_of_type(WORD_NODE);
	size_t ncat = nclasses + nwords;

	dict->num_categories = ncat;
	dict->num_categories_alloced = ncat + 2;
	dict->category = (Category*) malloc(
		dict->num_categories_alloced * sizeof(*dict->category));

printf("duude got %lu cats\n", ncat);

	HandleSeq allcl;
	local->asp->get_handles_by_type(allcl, WORD_CLASS_NODE);

	size_t j = 1;
	for (size_t i=0; i<allcl.size(); i++)
	{
		const Handle& wcl = allcl[i];

		dict->category[j].exp = make_exprs(dict, wcl);
		if (nullptr == dict->category[j].exp)
			continue;

		dict->category[j].name =
			string_set_add(wcl->get_name().c_str(), dict->string_set);
// printf("duude %lu catcl=%s\n", j, dict->category[j].name);

		size_t nwo = wcl->getIncomingSetSizeByType(MEMBER_LINK);
		dict->category[j].word = (const char**)
			malloc(nwo * sizeof(*dict->category[0].word));

		nwo = 0;
		for (const Handle& memb : wcl->getIncomingSetByType(MEMBER_LINK))
		{
			const Handle& wrd = memb->getOutgoingAtom(0);
			if (WORD_NODE != wrd->get_type()) continue;

			dict->category[j].word[nwo] =
				string_set_add(wrd->get_name().c_str(), dict->string_set);
//printf("duude %lu catl= %s %lu %s\n", j, dict->category[j].name, nwo, dict->category[j].word[nwo]);
			nwo++;
		}
		dict->category[j].num_words = nwo;
		j++;
	}

	HandleSeq allwo;
	local->asp->get_handles_by_type(allwo, WORD_NODE);

	for (size_t i=0; i<allwo.size(); i++)
	{
		dict->category[j].exp = make_exprs(dict, allwo[i]);
		if (nullptr == dict->category[j].exp)
			continue;

		dict->category[j].name =
			string_set_add(allwo[i]->get_name().c_str(), dict->string_set);

// printf("duude %lu catwo=>>%s<<\n", j, dict->category[j].name);

		dict->category[j].num_words = 1;
		dict->category[j].word =
			(const char**) malloc(sizeof(*dict->category[0].word));
		dict->category[j].word[0] = dict->category[j].name;
		j++;
	}

	j--;
printf("Expected num cats: %lu  Actual num cats: %lu\n", ncat, j);

	/* Free excess memory, if any */
	dict->num_categories_alloced = j + 2;
	dict->category = (Category*) realloc(dict->category,
		dict->num_categories_alloced * sizeof(*dict->category));

	/* Set the termination entry. */
	dict->num_categories = j;
	dict->category[j + 1].num_words = 0;
}

#endif // HAVE_ATOMESE
<commit_msg>Skip over empty cats<commit_after>/*
 * fetch-cats.cc
 *
 * Fetch everything; needed for generation.
 *
 * Copyright (c) 2022 Linas Vepstas <linasvepstas@gmail.com>
 */
#ifdef HAVE_ATOMESE

extern "C" {
#include "../link-includes.h"            // For Dictionary
#include "../dict-common/dict-common.h"  // for Dictionary_s
#include "lookup-atomese.h"
};

#include "local-as.h"
#include <opencog/nlp/types/atom_types.h>

using namespace opencog;

void as_add_categories(Dictionary dict)
{
	Local* local = (Local*) (dict->as_server);

	// Get all sections.
	if (local->stnp)
	{
		local->stnp->fetch_all_atoms_of_type(SECTION);
		local->stnp->barrier();
	}

	// Assume one category per word and word-class.
	// (i.e. that all words will have sections)
	size_t nclasses = local->asp->get_num_atoms_of_type(WORD_CLASS_NODE);
	size_t nwords = local->asp->get_num_atoms_of_type(WORD_NODE);
	size_t ncat = nclasses + nwords;

	dict->num_categories = ncat;
	dict->num_categories_alloced = ncat + 2;
	dict->category = (Category*) malloc(
		dict->num_categories_alloced * sizeof(*dict->category));

printf("duude got %lu cats\n", ncat);

	HandleSeq allcl;
	local->asp->get_handles_by_type(allcl, WORD_CLASS_NODE);

	size_t j = 1;
	for (size_t i=0; i<allcl.size(); i++)
	{
		const Handle& wcl = allcl[i];

		dict->category[j].exp = make_exprs(dict, wcl);
		if (nullptr == dict->category[j].exp)
			continue;

		// Crufty dicts can contain empty cats.
		size_t nwo = wcl->getIncomingSetSizeByType(MEMBER_LINK);
		if (0 == nwo)
			continue;

		dict->category[j].word = (const char**)
			malloc(nwo * sizeof(*dict->category[0].word));

		dict->category[j].name =
			string_set_add(wcl->get_name().c_str(), dict->string_set);
// printf("duude %lu catcl=%s\n", j, dict->category[j].name);

		nwo = 0;
		for (const Handle& memb : wcl->getIncomingSetByType(MEMBER_LINK))
		{
			const Handle& wrd = memb->getOutgoingAtom(0);
			if (WORD_NODE != wrd->get_type()) continue;

			dict->category[j].word[nwo] =
				string_set_add(wrd->get_name().c_str(), dict->string_set);
//printf("duude %lu catl= %s %lu %s\n", j, dict->category[j].name, nwo, dict->category[j].word[nwo]);
			nwo++;
		}
		dict->category[j].num_words = nwo;
		j++;
	}

	HandleSeq allwo;
	local->asp->get_handles_by_type(allwo, WORD_NODE);

	for (size_t i=0; i<allwo.size(); i++)
	{
		dict->category[j].exp = make_exprs(dict, allwo[i]);
		if (nullptr == dict->category[j].exp)
			continue;

		dict->category[j].name =
			string_set_add(allwo[i]->get_name().c_str(), dict->string_set);

// printf("duude %lu catwo=>>%s<<\n", j, dict->category[j].name);

		dict->category[j].num_words = 1;
		dict->category[j].word =
			(const char**) malloc(sizeof(*dict->category[0].word));
		dict->category[j].word[0] = dict->category[j].name;
		j++;
	}

	j--;
printf("Expected num cats: %lu  Actual num cats: %lu\n", ncat, j);

	/* Free excess memory, if any */
	dict->num_categories_alloced = j + 2;
	dict->category = (Category*) realloc(dict->category,
		dict->num_categories_alloced * sizeof(*dict->category));

	/* Set the termination entry. */
	dict->num_categories = j;
	dict->category[j + 1].num_words = 0;
}

#endif // HAVE_ATOMESE
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2014 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: optionsbrowser.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "optionsbrowser.h"
#include "ui_optionswidget.h"

#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

OptionsBrowser::OptionsBrowser(LiteApi::IApplication *app, QWidget *parent) :
    QDialog(parent),
    m_liteApp(app),
    ui(new Ui::OptionsWidget)
{
    ui->setupUi(this);
    connect(ui->listWidget,SIGNAL(itemSelectionChanged()),this,SLOT(itemSelectionChanged()));
    connect(ui->applayButton,SIGNAL(clicked()),this,SLOT(applayButton()));
    connect(ui->cancelButton,SIGNAL(clicked()),this,SLOT(reject()));
}

OptionsBrowser::~OptionsBrowser()
{
    delete ui;
    //delete m_widget;
}

QString OptionsBrowser::name() const
{
    return tr("Options");
}

QString OptionsBrowser::mimeType() const
{
    return "browser/options";
}

void OptionsBrowser::addOption(LiteApi::IOption *opt)
{
    if (!opt || !opt->widget()) {
        return;
    }

    QListWidgetItem *item = new QListWidgetItem;
    item->setIcon(opt->icon());
    item->setText(opt->name());
    item->setTextAlignment(Qt::AlignLeft);// | Qt::AlignHCenter);
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

    ui->listWidget->addItem(item);
    ui->stackedWidget->addWidget(opt->widget());
    m_widgetOptionMap.insert(item,opt);
}

int OptionsBrowser::execute()
{
    if (ui->listWidget->count() >= 1) {
        ui->listWidget->setCurrentItem(ui->listWidget->item(0));
#ifdef Q_OS_MAC
        this->setMinimumHeight(600);
#endif
    }
    return exec();
}

void OptionsBrowser::itemSelectionChanged()
{
    QListWidgetItem *item = ui->listWidget->currentItem();
    if (!item) {
        return;
    }
    LiteApi::IOption *opt = m_widgetOptionMap.value(item);
    if (opt) {
        opt->active();
        ui->stackedWidget->setCurrentWidget(opt->widget());
        ui->infoLabel->setText(QString("Name : %1    MimeType : %2").arg(opt->name()).arg(opt->mimeType()));
        opt->widget()->updateGeometry();
    }
}

void OptionsBrowser::applayButton()
{
    QListWidgetItem *item = ui->listWidget->currentItem();
    if (!item) {
        return;
    }
    LiteApi::IOption *opt = m_widgetOptionMap.value(item);
    if (opt) {
        opt->apply();
        emit applyOption(opt->mimeType());
    }
}
<commit_msg>update<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2014 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: optionsbrowser.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "optionsbrowser.h"
#include "ui_optionswidget.h"

#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

OptionsBrowser::OptionsBrowser(LiteApi::IApplication *app, QWidget *parent) :
    QDialog(parent),
    m_liteApp(app),
    ui(new Ui::OptionsWidget)
{
    ui->setupUi(this);
    connect(ui->listWidget,SIGNAL(itemSelectionChanged()),this,SLOT(itemSelectionChanged()));
    connect(ui->applayButton,SIGNAL(clicked()),this,SLOT(applayButton()));
    connect(ui->cancelButton,SIGNAL(clicked()),this,SLOT(reject()));
}

OptionsBrowser::~OptionsBrowser()
{
    delete ui;
    //delete m_widget;
}

QString OptionsBrowser::name() const
{
    return tr("Options");
}

QString OptionsBrowser::mimeType() const
{
    return "browser/options";
}

void OptionsBrowser::addOption(LiteApi::IOption *opt)
{
    if (!opt || !opt->widget()) {
        return;
    }

    QListWidgetItem *item = new QListWidgetItem;
    item->setIcon(opt->icon());
    item->setText(opt->name());
    item->setTextAlignment(Qt::AlignLeft);// | Qt::AlignHCenter);
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

    ui->listWidget->addItem(item);
    ui->stackedWidget->addWidget(opt->widget());
    m_widgetOptionMap.insert(item,opt);
}

int OptionsBrowser::execute()
{
    if (ui->listWidget->count() >= 1) {
        ui->listWidget->setCurrentItem(ui->listWidget->item(0));
        this->setMinimumHeight(600);
    }
    return exec();
}

void OptionsBrowser::itemSelectionChanged()
{
    QListWidgetItem *item = ui->listWidget->currentItem();
    if (!item) {
        return;
    }
    LiteApi::IOption *opt = m_widgetOptionMap.value(item);
    if (opt) {
        opt->active();
        ui->stackedWidget->setCurrentWidget(opt->widget());
        ui->infoLabel->setText(QString("Name : %1    MimeType : %2").arg(opt->name()).arg(opt->mimeType()));
        opt->widget()->updateGeometry();
    }
}

void OptionsBrowser::applayButton()
{
    QListWidgetItem *item = ui->listWidget->currentItem();
    if (!item) {
        return;
    }
    LiteApi::IOption *opt = m_widgetOptionMap.value(item);
    if (opt) {
        opt->apply();
        emit applyOption(opt->mimeType());
    }
}
<|endoftext|>


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

*/

#include "JointFrictionR.hpp"
#include <NewtonEulerDS.hpp>
#include <Interaction.hpp>
#include <boost/math/quaternion.hpp>
#include <BlockVector.hpp>
#include <cfloat>
#include <iostream>

// #define DEBUG_BEGIN_END_ONLY
// #define DEBUG_STDOUT
// #define DEBUG_MESSAGES
#include "debug.h"

/** Initialize a joint friction for a common case: a single axis with a
 * single friction, either positive or negative. For use with
 * NewtonImpactNSL. */
JointFrictionR::JointFrictionR(SP::NewtonEulerJointR joint, unsigned int axis)
  : NewtonEulerR()
  , _joint(joint)
  , _axis(std11::make_shared< std::vector<unsigned int> >())
{
  _axis->push_back(axis);
  _axisMin = axis;
  _axisMax = axis;
  assert( (_axisMax - _axisMin + 1) <= _joint->numberOfDoF() );
}

/** Initialize a multidimensional joint friction, e.g. the cone friction on
 * a ball joint. For use with NewtonImpactFrictionNSL size 2 or 3. */
JointFrictionR::JointFrictionR(SP::NewtonEulerJointR joint, SP::UnsignedIntVector axes)
  : NewtonEulerR()
  , _joint(joint)
  , _axis(axes)
{
  if (axes)
  {
    _axisMin = 100;
    _axisMax = 0;
    for (unsigned int i=0; i < _axis->size(); i++)
    {
      if ((*_axis)[i] > _axisMax) _axisMax = (*_axis)[i];
      if ((*_axis)[i] < _axisMin) _axisMin = (*_axis)[i];
    }
  }
  else
  {
    _axisMin = _axisMax = 0;
    _axis = std11::make_shared< std::vector<unsigned int> >();
    _axis->push_back(0);
  }

  assert( (_axisMax - _axisMin + 1) <= _joint->numberOfDoF() );
}

void JointFrictionR::computeh(double time, BlockVector& q0, SiconosVector& y)
{
  // Velocity-level constraint, no position-level h
  y.zero();
}

void JointFrictionR::computeJachq(double time, Interaction& inter, SP::BlockVector q0)
{
  unsigned int n = _axisMax - _axisMin + 1;
  assert(n==1); // For now, multi-axis support TODO

  if (!_jachqTmp || !(_jachqTmp->size(1) == q0->size() &&
                      _jachqTmp->size(0) == n))
  {
    _jachqTmp = std11::make_shared<SimpleMatrix>(n, q0->size());
  }

  // Compute the jacobian for the required range of axes
  _joint->computeJachqDoF(time, inter, q0, *_jachqTmp, _axisMin);

  // Copy indicated axes into the friction jacobian, negative and positive sides
  // NOTE trying ==1 using Relay, maybe don't need LCP formulation
  assert(_jachq->size(0)==1);
  for (unsigned int i=0; i<1; i++)
    for (unsigned int j=0; j<_jachq->size(1); j++) {
      _jachq->setValue(i,j,_jachqTmp->getValue((*_axis)[i]-_axisMin,j) * (i==1?1:-1));
    }
}

unsigned int JointFrictionR::numberOfConstraints()
{
  return _axis->size();
}
<commit_msg>[mechanics] Fix bad doxygen tag in JointFrictionR.cpp<commit_after>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2016 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/
/*! \file JointFrictionR.cpp
*/

#include "JointFrictionR.hpp"
#include <NewtonEulerDS.hpp>
#include <Interaction.hpp>
#include <boost/math/quaternion.hpp>
#include <BlockVector.hpp>
#include <cfloat>
#include <iostream>

// #define DEBUG_BEGIN_END_ONLY
// #define DEBUG_STDOUT
// #define DEBUG_MESSAGES
#include "debug.h"

/** Initialize a joint friction for a common case: a single axis with a
 * single friction, either positive or negative. For use with
 * NewtonImpactNSL. */
JointFrictionR::JointFrictionR(SP::NewtonEulerJointR joint, unsigned int axis)
  : NewtonEulerR()
  , _joint(joint)
  , _axis(std11::make_shared< std::vector<unsigned int> >())
{
  _axis->push_back(axis);
  _axisMin = axis;
  _axisMax = axis;
  assert( (_axisMax - _axisMin + 1) <= _joint->numberOfDoF() );
}

/** Initialize a multidimensional joint friction, e.g. the cone friction on
 * a ball joint. For use with NewtonImpactFrictionNSL size 2 or 3. */
JointFrictionR::JointFrictionR(SP::NewtonEulerJointR joint, SP::UnsignedIntVector axes)
  : NewtonEulerR()
  , _joint(joint)
  , _axis(axes)
{
  if (axes)
  {
    _axisMin = 100;
    _axisMax = 0;
    for (unsigned int i=0; i < _axis->size(); i++)
    {
      if ((*_axis)[i] > _axisMax) _axisMax = (*_axis)[i];
      if ((*_axis)[i] < _axisMin) _axisMin = (*_axis)[i];
    }
  }
  else
  {
    _axisMin = _axisMax = 0;
    _axis = std11::make_shared< std::vector<unsigned int> >();
    _axis->push_back(0);
  }

  assert( (_axisMax - _axisMin + 1) <= _joint->numberOfDoF() );
}

void JointFrictionR::computeh(double time, BlockVector& q0, SiconosVector& y)
{
  // Velocity-level constraint, no position-level h
  y.zero();
}

void JointFrictionR::computeJachq(double time, Interaction& inter, SP::BlockVector q0)
{
  unsigned int n = _axisMax - _axisMin + 1;
  assert(n==1); // For now, multi-axis support TODO

  if (!_jachqTmp || !(_jachqTmp->size(1) == q0->size() &&
                      _jachqTmp->size(0) == n))
  {
    _jachqTmp = std11::make_shared<SimpleMatrix>(n, q0->size());
  }

  // Compute the jacobian for the required range of axes
  _joint->computeJachqDoF(time, inter, q0, *_jachqTmp, _axisMin);

  // Copy indicated axes into the friction jacobian, negative and positive sides
  // NOTE trying ==1 using Relay, maybe don't need LCP formulation
  assert(_jachq->size(0)==1);
  for (unsigned int i=0; i<1; i++)
    for (unsigned int j=0; j<_jachq->size(1); j++) {
      _jachq->setValue(i,j,_jachqTmp->getValue((*_axis)[i]-_axisMin,j) * (i==1?1:-1));
    }
}

unsigned int JointFrictionR::numberOfConstraints()
{
  return _axis->size();
}
<|endoftext|>


<commit_before>/*********************************************
* Author: Jun Jiang - jiangjun4@sina.com
* Created: 2017-06-01 11:22
* Last modified: 2017-06-01 11:22
* Filename: TestRNN.cpp
* Description:
**********************************************/

#include "rnn/RNN.h"
#include "utils/Log.h"
#include "utils/RNNHelper.h"

int main(int argc, char** argv){
    abcdl::utils::log::set_min_log_level(abcdl::utils::log::INFO);
    abcdl::utils::log::initialize_log(argc, argv);

	abcdl::utils::RNNHelper helper(8000);

	//std::map<std::string, size_t> map;
	//helper.read_word2index("data/rnn/word_to_index", map);

	std::vector<abcdl::algebra::Mat*> data_seq_data;
	std::vector<abcdl::algebra::Mat*> data_seq_label;
	if(!helper.read_seq_data("data/rnn/train_seq_data", data_seq_data, "data/rnn/train_seq_label", data_seq_label, 1000)){
		return -1;
	}

	data_seq_data[0]->display("|");

    printf("Start training....\n");

    abcdl::rnn::RNN rnn(8000, 100);
    rnn.train(data_seq_data, data_seq_label);

	for(auto&& d : data_seq_data){
		delete d;
	}
	data_seq_data.clear();

	for(auto&& d : data_seq_label){
		delete d;
	}
	data_seq_label.clear();
}
<commit_msg>initialize<commit_after>/*********************************************
* Author: Jun Jiang - jiangjun4@sina.com
* Created: 2017-06-01 11:22
* Last modified: 2017-06-01 11:22
* Filename: TestRNN.cpp
* Description:
**********************************************/

#include "rnn/RNN.h"
#include "utils/Log.h"
#include "utils/RNNHelper.h"

int main(int argc, char** argv){
    abcdl::utils::log::set_min_log_level(abcdl::utils::log::INFO);
    abcdl::utils::log::initialize_log(argc, argv);

	abcdl::utils::RNNHelper helper(8000);

	//std::map<std::string, size_t> map;
	//helper.read_word2index("data/rnn/word_to_index", map);

    const size_t sample_size = 10000;
	std::vector<abcdl::algebra::Mat*> data_seq_data;
	std::vector<abcdl::algebra::Mat*> data_seq_label;
	if(!helper.read_seq_data("data/rnn/train_seq_data", data_seq_data, "data/rnn/train_seq_label", data_seq_label, sample_size)){
		return -1;
	}

    LOG(INFO) << "RNN Start training....";

    abcdl::rnn::RNN rnn(8000, 100);
    rnn.train(data_seq_data, data_seq_label);

	for(auto&& d : data_seq_data){
		delete d;
	}
	data_seq_data.clear();

	for(auto&& d : data_seq_label){
		delete d;
	}
	data_seq_label.clear();
}
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/* Copyright (c) FFLAS-FFPACK
* ========LICENCE========
* This file is part of the library FFLAS-FFPACK.
*
* FFLAS-FFPACK is free software: you can redistribute it and/or modify
* it under the terms of the  GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
* ========LICENCE========
*/

#include <iostream>
#include <givaro/modular.h>
#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/fflas-ffpack.h"
#include "fflas-ffpack/utils/fflas_io.h"

using namespace std;

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

	if (argc != 3){
		std::cerr<<"Usage: pluq <p> <matrix>"<<std::endl;
		return -1;
	}

	int p = atoi(argv[1]);
	std::string file = argv[2];
	size_t m,n;

		// Creating the finite field Z/qZ
	Givaro::Modular<double> F(p);

		// Reading the matrix from a file
	double *A;
	FFLAS::ReadMatrix (file.c_str(),F,m,n,A);

    size_t * P = FFLAS::fflas_new<size_t>(m);
    size_t * Q = FFLAS::fflas_new<size_t>(n);

    FFPACK::PLUQ (F, FFLAS::FflasNonUnit, m, n, A, n, P, Q);

	FFLAS::WritePermutation (std::cout<<"P = "<<std::endl,P,m);
	FFLAS::WriteMatrix (std::cout<<"LU = "<<std::endl,F,m,n,A,n)<< " modulo " << p << std::endl;
	if(m == n)
	{
		size_t lda = n;
		//Display L (which has unit diagonal)
		std::cout<<"L = "<<std::endl;
		for(size_t i = 0; i < m; ++i){
			for(size_t j = 0; j < n; ++j)
			{
				if(i == j)
					std::cout<<1<<"\t";
				else if(i < j)
					std::cout<<0<<"\t";
				else
					std::cout<<A[j+i*lda]<<"\t";
			}
			std::cout<<std::endl;
		}
		std::cout<<"\n modulo "<<p<<std::endl;

		//Display U
		std::cout<<"U = "<<std::endl;
		for(size_t i = 0; i < m; ++i){
			for(size_t j = 0; j < n; ++j)
			{
				if(i > j)
					std::cout<<0<<"\t";
				else
					std::cout<<A[j+i*lda]<<"\t";
			}
			std::cout<<std::endl;
		}
		std::cout<<"\n modulo "<<p<<std::endl;

	}
	else if(m > n)
	{
		size_t lda = n;
		//Display L
		std::cout<<"L = "<<std::endl;
		for(size_t i = 0; i < m; ++i){
			for(size_t j = 0; j < m; ++j)
			{
				if(i == j)
					std::cout<<1<<"\t";
				else if(i < j)
					std::cout<<0<<"\t";
				else
					std::cout<<A[j+i*lda]<<"\t";
			}
			std::cout<<std::endl;
		}
		std::cout<<"\n modulo "<<p<<std::endl;

		//Display U
		std::cout<<"U = "<<std::endl;
		for(size_t i = 0; i < m; ++i){
			for(size_t j = 0; j < n; ++j)
			{
				if(i > j)
					std::cout<<0<<"\t";
				else
					std::cout<<A[j+i*lda]<<"\t";
			}
			std::cout<<std::endl;
		}
		std::cout<<"\n modulo "<<p<<std::endl;
	}

	FFLAS::WritePermutation (std::cout<<"Q = "<<std::endl,Q,n);

    FFLAS::fflas_delete( P);
    FFLAS::fflas_delete( Q);
    FFLAS::fflas_delete( A);

	return 0;
}

<commit_msg>Simplified full display of L and U<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/* Copyright (c) FFLAS-FFPACK
* ========LICENCE========
* This file is part of the library FFLAS-FFPACK.
*
* FFLAS-FFPACK is free software: you can redistribute it and/or modify
* it under the terms of the  GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
* ========LICENCE========
*/

#include <iostream>
#include <givaro/modular.h>
#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/fflas-ffpack.h"
#include "fflas-ffpack/utils/fflas_io.h"

using namespace std;

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

	if (argc != 3){
		std::cerr<<"Usage: pluq <p> <matrix>"<<std::endl;
		return -1;
	}

	int p = atoi(argv[1]);
	std::string file = argv[2];
	size_t m,n;

		// Creating the finite field Z/qZ
	Givaro::Modular<double> F(p);

		// Reading the matrix from a file
	double *A;
	FFLAS::ReadMatrix (file.c_str(),F,m,n,A);

    size_t * P = FFLAS::fflas_new<size_t>(m);
    size_t * Q = FFLAS::fflas_new<size_t>(n);

    FFPACK::PLUQ (F, FFLAS::FflasNonUnit, m, n, A, n, P, Q);

	FFLAS::WritePermutation (std::cout<<"P = "<<std::endl,P,m);

	size_t lda = n;
	//Display L (which has unit diagonal)
	std::cout<<"L = "<<std::endl;
	for(size_t i = 0; i < m; ++i){
		for(size_t j = 0; j < m; ++j)
		{
			if(i == j)
				std::cout<<1<<"\t";
			else if(i < j)
				std::cout<<0<<"\t";
			else
				std::cout<<A[j+i*lda]<<"\t";
		}
		std::cout<<std::endl;
	}
	std::cout<<"\n modulo "<<p<<std::endl;

	//Display U
	std::cout<<"U = "<<std::endl;
	for(size_t i = 0; i < m; ++i){
		for(size_t j = 0; j < n; ++j)
		{
			if(i > j)
				std::cout<<0<<"\t";
			else
				std::cout<<A[j+i*lda]<<"\t";
		}
		std::cout<<std::endl;
	}
	std::cout<<"\n modulo "<<p<<std::endl;
	FFLAS::WritePermutation (std::cout<<"Q = "<<std::endl,Q,n);

    FFLAS::fflas_delete( P);
    FFLAS::fflas_delete( Q);
    FFLAS::fflas_delete( A);

	return 0;
}

<|endoftext|>


<commit_before>#include <stdlib.h>
#include <time.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>

#if defined(__linux__) || defined(__FreeBSD__)
#include <arpa/nameser.h>
#else
#include <nameser.h>
#endif

#include <resolv.h>

#include "name_pkt.hpp"

#define SA struct sockaddr

void usage(char* filename);
char* get_resolver(int i);
int get_resolver_count(void);

int main(int argc, char** argv)
{
    if (!(argc == 3 || argc == 4)) usage(argv[0]);

    srand((unsigned)time(NULL));
    uint16_t ns_id = (rand()&0x0000FFFF);

    std::string name(argv[1]);

    name_pkt npkt;
    npkt.n_set_id(ns_id);
    npkt.n_set_flags(0x0100);
    npkt.n_create_rr_questionA(name);
    npkt.n_build_payload();

    ssize_t len;
    socklen_t sin_size = sizeof(struct sockaddr_in);

    int sockfd;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in sin1;
    struct sockaddr_in sin2;
    unsigned char buf[BUFSIZ];

    memset(&sin1, 0, sizeof(sin1));
    memset(&sin2, 0, sizeof(sin2));
    memset(buf, 0, BUFSIZ);

    res_init();
    //printf("%d\n", get_resolver_count());
    //printf("%s\n", get_resolver(0));

    sin1.sin_family = AF_INET;
    sin1.sin_port = htons(53);
    if (argc == 2) {
        inet_pton(AF_INET, get_resolver(0), &sin1.sin_addr);
        //printf("%s\n", get_resolver(0));
    }
    if (argc == 3) {
        inet_pton(AF_INET, argv[2], &sin1.sin_addr);
    }

    printf("%s\n", argv[3]);
    int a;
    if (argc == 4) {
        inet_pton(AF_INET, argv[2], &sin1.sin_addr);
        sin2.sin_family = AF_INET;
        sin2.sin_port = htons(atoi(argv[3]));
        inet_pton(AF_INET, argv[2], &sin2.sin_addr);
        if (bind(sockfd, (struct sockaddr*)&sin2, sizeof(sin2)) < 0) {
            perror("bind");
            exit(1);
        }
        //printf("%d\n", err);
    }

    /*
    struct timeval {
        time_t       tv_sec;
        suseconds_t  tv_usec;
    };
    */

    struct timeval prev;
    struct timeval current;

    int s_retval;
    fd_set s_fd;

    /*
    struct timeval t_val;
    memset(&t_val, 0, sizeof(t_val));
    t_val.tv_sec = 2;
    */

    gettimeofday(&prev, NULL);
    sendto(sockfd, npkt.n_payload(), npkt.n_payload_size(), 0, (SA*)&sin1, sizeof(sin1));

    re:
    FD_ZERO(&s_fd);
    FD_SET(sockfd, &s_fd);
    //s_retval = select((sockfd+1), &s_fd, NULL, NULL, &t_val);
    s_retval = select((sockfd+1), &s_fd, NULL, NULL, NULL);
    if (s_retval <= 0) {
        if (s_retval == -1) {
            perror("select");
            close(sockfd);
            exit(1);
        }
        if (s_retval == 0) {
            printf("2.000000 %s timeout\n", argv[1]);
            close(sockfd);
            return 0;
        }
    }

    len = recvfrom(sockfd, buf, BUFSIZ, 0, (SA*)&sin2, &sin_size);
    gettimeofday(&current, NULL);

    time_t sec;
    suseconds_t usec;
    if (current.tv_sec == prev.tv_sec) {
        sec = current.tv_sec - prev.tv_sec;
        usec = current.tv_usec - prev.tv_usec;
    }

    else if (current.tv_sec != prev.tv_sec) {
        int carry = 1000000;
        sec = current.tv_sec - prev.tv_sec;
        if (prev.tv_usec > current.tv_usec) {
            usec = carry - prev.tv_usec + current.tv_usec;
            sec--;
            if (usec > carry) {
                usec = usec - carry;
                sec++;
            }
        } else {
            usec = current.tv_usec - prev.tv_usec;
        }
    }

    if (len == -1) { exit(1); }

    unsigned int name_id;
    ns_msg ns_handle;
    memset(&ns_handle, 0, sizeof(ns_handle));
    ns_initparse((const unsigned char*)buf,  len, &ns_handle);
    name_id = ns_msg_id(ns_handle);
    if (name_id != ns_id) {
        goto re;
    }

    int count;
    ns_rr rr;
    memset(&rr, 0, sizeof(rr));
    count = ns_msg_count(ns_handle, ns_s_an);

    if (count == 0) {
#ifdef __linux__
        printf("%lu.%06li %s nxdomain\n", sec, usec, argv[1]);
#else
        printf("%lu.%06d %s nxdomain\n", sec, usec, argv[1]);
#endif
        close(sockfd);
        return 0;
    } else {
#ifdef __linux__
        printf("%lu.%06li ", sec, usec);
#else
        printf("%lu.%06d ", sec, usec);
#endif
    }

    int i;
    int type;
    //char rdata_buffer[BUFSIZ];
    for (i=0; i<count; i++) {
        ns_parserr(&ns_handle, ns_s_an, i, &rr);
        printf("%s", argv[1]);
        printf(" ");

        /*
        memset(rdata_buffer, '\0', BUFSIZ);
        ret = ns_name_uncompress(
            ns_msg_base(ns_handle),
            ns_msg_end(ns_handle),
            ns_rr_rdata(rr),
            rdata_buffer,
            BUFSIZ);
        printf("%s", rdata_buffer);
        */

        uint32_t rbuf;
        struct in_addr* addr;
        memcpy(&rbuf, ns_rr_rdata(rr), sizeof(rbuf));
        addr = (struct in_addr*)&rbuf;
        printf("%s", inet_ntoa(*addr));
        printf(" ");
        type = ns_rr_type(rr);
        // type 1 : a
        if(type == 1) {
            printf("A");
            printf(" ");
        }
        printf("\n");
        /*
        // type 28: aaaa
        if(type == 28) {
            printf(":AAAA\n");
        }
        */
    }
    close(sockfd);

    return 0;
}

void usage(char* filename){
    printf("%s [hostname]\n", filename);
    printf("%s [hostname] [dns server]\n", filename);
    printf("%s [hostname] [dns server] [source port]\n", filename);
    exit(-1);
}

char* get_resolver(int i)
{
    struct sockaddr_in sin;
    memcpy(&sin, &(_res.nsaddr_list[i]), sizeof(struct sockaddr_in));
    return inet_ntoa(sin.sin_addr);
}

int get_resolver_count(void)
{
    return _res.nscount;
}
<commit_msg>update<commit_after>#include <stdlib.h>
#include <time.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>

#if defined(__linux__) || defined(__FreeBSD__)
#include <arpa/nameser.h>
#else
#include <nameser.h>
#endif

#include <resolv.h>

#include "name_pkt.hpp"

#define SA struct sockaddr

void usage(char* filename);
char* get_resolver(int i);
int get_resolver_count(void);

int main(int argc, char** argv)
{
    if (!(argc == 3 || argc == 4)) usage(argv[0]);

    srand((unsigned)time(NULL));
    uint16_t ns_id = (rand()&0x0000FFFF);

    std::string name(argv[1]);

    name_pkt npkt;
    npkt.n_set_id(ns_id);
    npkt.n_set_flags(0x0100);
    npkt.n_create_rr_questionA(name);
    npkt.n_build_payload();

    ssize_t len;
    socklen_t sin_size = sizeof(struct sockaddr_in);

    int sockfd;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in sin1;
    struct sockaddr_in sin2;
    unsigned char buf[BUFSIZ];

    memset(&sin1, 0, sizeof(sin1));
    memset(&sin2, 0, sizeof(sin2));
    memset(buf, 0, BUFSIZ);

    res_init();
    //printf("%d\n", get_resolver_count());
    //printf("%s\n", get_resolver(0));

    sin1.sin_family = AF_INET;
    sin1.sin_port = htons(53);
    if (argc == 2) {
        inet_pton(AF_INET, get_resolver(0), &sin1.sin_addr);
        //printf("%s\n", get_resolver(0));
    }
    if (argc == 3) {
        inet_pton(AF_INET, argv[2], &sin1.sin_addr);
    }

    printf("%s\n", argv[3]);
    int a;
    if (argc == 4) {
        inet_pton(AF_INET, argv[2], &sin1.sin_addr);
        sin2.sin_family = AF_INET;
        sin2.sin_port = htons(atoi(argv[3]));
        inet_pton(AF_INET, argv[2], &sin2.sin_addr);
        if (bind(sockfd, (struct sockaddr*)&sin2, sizeof(sin2)) < 0) {
            perror("bind");
            exit(1);
        }
        //printf("%d\n", err);
    }

    /*
    struct timeval {
        time_t       tv_sec;
        suseconds_t  tv_usec;
    };
    */

    struct timeval prev;
    struct timeval current;

    int s_retval;
    fd_set s_fd;

    /*
    struct timeval t_val;
    memset(&t_val, 0, sizeof(t_val));
    t_val.tv_sec = 2;
    */

    gettimeofday(&prev, NULL);
    sendto(sockfd, npkt.n_payload(), npkt.n_payload_size(), 0, (SA*)&sin1, sizeof(sin1));

    re:
    FD_ZERO(&s_fd);
    FD_SET(sockfd, &s_fd);
    //s_retval = select((sockfd+1), &s_fd, NULL, NULL, &t_val);
    s_retval = select((sockfd+1), &s_fd, NULL, NULL, NULL);
    if (s_retval <= 0) {
        if (s_retval == -1) {
            perror("select");
            close(sockfd);
            exit(1);
        }
        if (s_retval == 0) {
            printf("2.000000 %s timeout\n", argv[1]);
            close(sockfd);
            return 0;
        }
    }

    len = recvfrom(sockfd, buf, BUFSIZ, 0, (SA*)&sin2, &sin_size);
    gettimeofday(&current, NULL);

    time_t sec;
    suseconds_t usec;
    if (current.tv_sec == prev.tv_sec) {
        sec = current.tv_sec - prev.tv_sec;
        usec = current.tv_usec - prev.tv_usec;
    }

    else if (current.tv_sec != prev.tv_sec) {
        int carry = 1000000;
        sec = current.tv_sec - prev.tv_sec;
        if (prev.tv_usec > current.tv_usec) {
            usec = carry - prev.tv_usec + current.tv_usec;
            sec--;
            if (usec > carry) {
                usec = usec - carry;
                sec++;
            }
        } else {
            usec = current.tv_usec - prev.tv_usec;
        }
    }

    if (len == -1) { exit(1); }

    unsigned int name_id;
    ns_msg ns_handle;
    memset(&ns_handle, 0, sizeof(ns_handle));
    ns_initparse((const unsigned char*)buf,  len, &ns_handle);
    name_id = ns_msg_id(ns_handle);
    if (name_id != ns_id) {
        goto re;
    }

    int count;
    ns_rr rr;
    memset(&rr, 0, sizeof(rr));
    count = ns_msg_count(ns_handle, ns_s_an);

    if (count == 0) {
#ifdef __linux__
        printf("%lu.%06li %s nxdomain\n", sec, usec, argv[1]);
#elif __FreeBSD__
        printf("%lu.%06ld %s nxdomain\n", sec, usec, argv[1]);
#else
        printf("%lu.%06d %s nxdomain\n", sec, usec, argv[1]);
#endif
        close(sockfd);
        return 0;
    } else {
#ifdef __linux__
        printf("%lu.%06li ", sec, usec);
#elif __FreeBSD__
        printf("%lu.%06ld ", sec, usec);
#else
        printf("%lu.%06d ", sec, usec);
#endif
    }

    int i;
    int type;
    //char rdata_buffer[BUFSIZ];
    for (i=0; i<count; i++) {
        ns_parserr(&ns_handle, ns_s_an, i, &rr);
        printf("%s", argv[1]);
        printf(" ");

        /*
        memset(rdata_buffer, '\0', BUFSIZ);
        ret = ns_name_uncompress(
            ns_msg_base(ns_handle),
            ns_msg_end(ns_handle),
            ns_rr_rdata(rr),
            rdata_buffer,
            BUFSIZ);
        printf("%s", rdata_buffer);
        */

        uint32_t rbuf;
        struct in_addr* addr;
        memcpy(&rbuf, ns_rr_rdata(rr), sizeof(rbuf));
        addr = (struct in_addr*)&rbuf;
        printf("%s", inet_ntoa(*addr));
        printf(" ");
        type = ns_rr_type(rr);
        // type 1 : a
        if(type == 1) {
            printf("A");
            printf(" ");
        }
        printf("\n");
        /*
        // type 28: aaaa
        if(type == 28) {
            printf(":AAAA\n");
        }
        */
    }
    close(sockfd);

    return 0;
}

void usage(char* filename){
    printf("%s [hostname]\n", filename);
    printf("%s [hostname] [dns server]\n", filename);
    printf("%s [hostname] [dns server] [source port]\n", filename);
    exit(-1);
}

char* get_resolver(int i)
{
    struct sockaddr_in sin;
    memcpy(&sin, &(_res.nsaddr_list[i]), sizeof(struct sockaddr_in));
    return inet_ntoa(sin.sin_addr);
}

int get_resolver_count(void)
{
    return _res.nscount;
}
<|endoftext|>


<commit_before>/**
 * @file       BlynkDebug.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2015
 * @brief      Debug utilities for Arduino
 */
#include "BlynkDebug.h"
#include "application.h"

size_t BlynkFreeRam()
{
    return 0;
}

void BlynkReset()
{
    System.reset();
    for(;;); // To make compiler happy
}

void BlynkFatal()
{
    delay(10000L);
    BlynkReset();
}
<commit_msg>Delete BlynkDebug.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>- VBE: update the variables for the old screen dimensions after redrawing<commit_after><|endoftext|>


<commit_before>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-21

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReader.h"

#include "TChain.h"
#include "TDirectory.h"
#include "TTreeReaderValue.h"

/** \class TTreeReader
 TTreeReader is a simple, robust and fast interface to read values from a TTree,
 TChain or TNtuple.

 It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data.

 Example code can be found in
 tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and
 tutorials/trees/h1analysisTreeReader.C for a TSelector.

 Roottest contains an
 example
 showing the full power.

A simpler analysis example - the one from the tutorials - can be found below:
it histograms a function of the px and py branches.

~~~{.cpp}
// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)

#include "TFile.h
#include "TH1F.h
#include "TTreeReader.h
#include "TTreeReaderValue.h

void hsimpleReader() {
   // Create a histogram for the values we read.
   TH1F("h1", "ntuple", 100, -4, 4);

   // Open the file containing the tree.
   TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");

   // Create a TTreeReader for the tree, for instance by passing the
   // TTree's name and the TDirectory / TFile it is in.
   TTreeReader myReader("ntuple", myFile);

   // The branch "px" contains floats; access them as myPx.
   TTreeReaderValue<Float_t> myPx(myReader, "px");
   // The branch "py" contains floats, too; access those as myPy.
   TTreeReaderValue<Float_t> myPy(myReader, "py");

   // Loop over all entries of the TTree or TChain.
   while (myReader.Next()) {
      // Just access the data as if myPx and myPy were iterators (note the '*'
      // in front of them):
      myHist->Fill(*myPx + *myPy);
   }

   myHist->Draw();
}
~~~

A more complete example including error handling and a few combinations of
TTreeReaderValue and TTreeReaderArray would look like this:

~~~{.cpp}
#include <TFile.h>
#include <TH1.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

#include "TriggerInfo.h"
#include "Muon.h"
#include "Tau.h"

#include <vector>
#include <iostream>

bool CheckValue(ROOT::TTreeReaderValueBase* value) {
   if (value->GetSetupStatus() < 0) {
      std::cerr << "Error " << value->GetSetupStatus()
                << "setting up reader for " << value->GetBranchName() << '\n';
      return false;
   }
   return true;
}

// Analyze the tree "MyTree" in the file passed into the function.
// Returns false in case of errors.
bool analyze(TFile* file) {
   // Create a TTreeReader named "MyTree" from the given TDirectory.
   // The TTreeReader gives access to the TTree to the TTreeReaderValue and
   // TTreeReaderArray objects. It knows the current entry number and knows
   // how to iterate through the TTree.
   TTreeReader reader("MyTree", file);

   // Read a single float value in each tree entries:
   TTreeReaderValue<float> weight(reader, "event.weight");
   if (!CheckValue(weight)) return false;

   // Read a TriggerInfo object from the tree entries:
   TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
   if (!CheckValue(triggerInfo)) return false;

   //Read a vector of Muon objects from the tree entries:
   TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
   if (!CheckValue(muons)) return false;

   //Read the pT for all jets in the tree entry:
   TTreeReaderArray<double> jetPt(reader, "jets.pT");
   if (!CheckValue(jetPt)) return false;

   // Read the taus in the tree entry:
   TTreeReaderArray<Tau> taus(reader, "taus");
   if (!CheckValue(taus)) return false;

   // Now iterate through the TTree entries and fill a histogram.

   TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);

   while (reader.Next()) {

      if (reader.GetEntryStatus() == kEntryValid) {
         std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
      } else {
         switch (reader.GetEntryStatus()) {
         kEntryValid:
            // Handled above.
            break;
         kEntryNotLoaded:
            std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
            break;
         kEntryNoTree:
            std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
            break;
         kEntryNotFound:
            // Can't really happen as TTreeReader::Next() knows when to stop.
            std::cerr << "Error: The entry number doe not exist\n";
            break;
         kEntryChainSetupError:
            std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
            break;
         kEntryChainFileError:
            std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
            break;
         kEntryDictionaryError:
            std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
            break;
         }
         return false;
      }

      // Access the TriggerInfo object as if it's a pointer.
      if (!triggerInfo->hasMuonL1())
         continue;

      // Ditto for the vector<Muon>.
      if (!muons->size())
         continue;

      // Access the jetPt as an array, whether the TTree stores this as
      // a std::vector, std::list, TClonesArray or Jet* C-style array, with
      // fixed or variable array size.
      if (jetPt.GetSize() < 2 || jetPt[0] < 100)
         continue;

      // Access the array of taus.
      if (!taus.IsEmpty()) {
         float currentWeight = *weight;
         for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) {
            // Access a float value - need to dereference as TTreeReaderValue
            // behaves like an iterator
            hist->Fill(taus[iTau].eta(), currentWeight);
         }
      }
   } // TTree entry / event loop
}
~~~
*/

ClassImp(TTreeReader)

using namespace ROOT::Internal;

////////////////////////////////////////////////////////////////////////////////
/// Access data from tree.

TTreeReader::TTreeReader(TTree* tree):
   fTree(tree),
   fDirectory(0),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fTree) {
      Error("TTreeReader", "TTree is NULL!");
   } else {
      Initialize();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Access data from the tree called keyname in the directory (e.g. TFile)
/// dir, or the current directory if dir is NULL. If keyname cannot be
/// found, or if it is not a TTree, IsZombie() will return true.

TTreeReader::TTreeReader(const char* keyname, TDirectory* dir /*= NULL*/):
   fTree(0),
   fDirectory(dir),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fDirectory) fDirectory = gDirectory;
   fDirectory->GetObject(keyname, fTree);
   Initialize();
}

////////////////////////////////////////////////////////////////////////////////
/// Tell all value readers that the tree reader does not exist anymore.

TTreeReader::~TTreeReader()
{
   for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
           i = fValues.begin(), e = fValues.end(); i != e; ++i) {
      (*i)->MarkTreeReaderUnavailable();
   }
   delete fDirector;
   fProxies.SetOwner();
}

////////////////////////////////////////////////////////////////////////////////
/// Initialization of the director.

void TTreeReader::Initialize()
{
   if (!fTree) {
      MakeZombie();
      fEntryStatus = kEntryNoTree;
   } else {
      fDirector = new ROOT::Internal::TBranchProxyDirector(fTree, -1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set the range of entries to be processed.
/// If last > first, this call is equivalent to
/// `SetEntry(first); SetLastEntry(last);`. Otherwise `last` is ignored and
/// only `first` is set.
/// \return the EEntryStatus that would be returned by SetEntry(first)

TTreeReader::EEntryStatus TTreeReader::SetEntriesRange(Long64_t first, Long64_t last)
{
   if(last > first)
      fLastEntry = last;
   else
      fLastEntry = -1;
   return SetEntry(first);
}

////////////////////////////////////////////////////////////////////////////////
///Returns the index of the current entry being read

Long64_t TTreeReader::GetCurrentEntry() const {
   if (!fDirector) return 0;
   Long64_t currentTreeEntry = fDirector->GetReadEntry();
   if (fTree->IsA() == TChain::Class() && currentTreeEntry >= 0) {
      return ((TChain*)fTree)->GetChainEntryNumber(currentTreeEntry);
   }
   return currentTreeEntry;
}

////////////////////////////////////////////////////////////////////////////////
/// Load an entry into the tree, return the status of the read.
/// For chains, entry is the global (i.e. not tree-local) entry number, unless
/// `local` is `true`, in which case `entry` specifies the entry number within
/// the current tree. This is needed for instance for TSelector::Process().

TTreeReader::EEntryStatus TTreeReader::SetEntryBase(Long64_t entry, Bool_t local)
{
   if (!fTree) {
      fEntryStatus = kEntryNoTree;
      return fEntryStatus;
   }

   TTree* prevTree = fDirector->GetTree();

   Int_t treeNumInChainBeforeLoad = fTree->GetTreeNumber();

   TTree* treeToCallLoadOn = local ? fTree->GetTree() : fTree;
   Long64_t loadResult = treeToCallLoadOn->LoadTree(entry);

   if (loadResult == -2) {
      fEntryStatus = kEntryNotFound;
      return fEntryStatus;
   }

   if (treeNumInChainBeforeLoad != fTree->GetTreeNumber()) {
      fDirector->SetTree(fTree->GetTree());
   }

   if (!prevTree || fDirector->GetReadEntry() == -1 || !fProxiesSet) {
      // Tell readers we now have a tree
      for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
              i = fValues.begin(); i != fValues.end(); ++i) { // Iterator end changes when parameterized arrays are read
         (*i)->CreateProxy();

         if (!(*i)->GetProxy()){
            fEntryStatus = kEntryDictionaryError;
            return fEntryStatus;
         }
      }
      // If at least one proxy was there and no error occurred, we assume the proxies to be set.
      fProxiesSet = !fValues.empty();
   }
   if (fLastEntry >= 0 && loadResult >= fLastEntry) {
      fEntryStatus = kEntryLast;
      return fEntryStatus;
   }
   fDirector->SetReadEntry(loadResult);
   fEntryStatus = kEntryValid;
   return fEntryStatus;
}

////////////////////////////////////////////////////////////////////////////////
/// Set (or update) the which tree to reader from. tree can be
/// a TTree or a TChain.

void TTreeReader::SetTree(TTree* tree)
{
   fTree = tree;
   if (fTree) {
      ResetBit(kZombie);
      if (fTree->InheritsFrom(TChain::Class())) {
         SetBit(kBitIsChain);
      }
   }

   if (!fDirector) {
      Initialize();
   }
   else {
      fDirector->SetTree(fTree);
      fDirector->SetReadEntry(-1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Add a value reader for this tree.

void TTreeReader::RegisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   fValues.push_back(reader);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove a value reader for this tree.

void TTreeReader::DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
      = std::find(fValues.begin(), fValues.end(), reader);
   if (iReader == fValues.end()) {
      Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
      return;
   }
   fValues.erase(iReader);
}
<commit_msg>Use the global chain entry to check if the upper limit is reached.<commit_after>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-21

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReader.h"

#include "TChain.h"
#include "TDirectory.h"
#include "TTreeReaderValue.h"

/** \class TTreeReader
 TTreeReader is a simple, robust and fast interface to read values from a TTree,
 TChain or TNtuple.

 It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data.

 Example code can be found in
 tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and
 tutorials/trees/h1analysisTreeReader.C for a TSelector.

 Roottest contains an
 example
 showing the full power.

A simpler analysis example - the one from the tutorials - can be found below:
it histograms a function of the px and py branches.

~~~{.cpp}
// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)

#include "TFile.h
#include "TH1F.h
#include "TTreeReader.h
#include "TTreeReaderValue.h

void hsimpleReader() {
   // Create a histogram for the values we read.
   TH1F("h1", "ntuple", 100, -4, 4);

   // Open the file containing the tree.
   TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");

   // Create a TTreeReader for the tree, for instance by passing the
   // TTree's name and the TDirectory / TFile it is in.
   TTreeReader myReader("ntuple", myFile);

   // The branch "px" contains floats; access them as myPx.
   TTreeReaderValue<Float_t> myPx(myReader, "px");
   // The branch "py" contains floats, too; access those as myPy.
   TTreeReaderValue<Float_t> myPy(myReader, "py");

   // Loop over all entries of the TTree or TChain.
   while (myReader.Next()) {
      // Just access the data as if myPx and myPy were iterators (note the '*'
      // in front of them):
      myHist->Fill(*myPx + *myPy);
   }

   myHist->Draw();
}
~~~

A more complete example including error handling and a few combinations of
TTreeReaderValue and TTreeReaderArray would look like this:

~~~{.cpp}
#include <TFile.h>
#include <TH1.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

#include "TriggerInfo.h"
#include "Muon.h"
#include "Tau.h"

#include <vector>
#include <iostream>

bool CheckValue(ROOT::TTreeReaderValueBase* value) {
   if (value->GetSetupStatus() < 0) {
      std::cerr << "Error " << value->GetSetupStatus()
                << "setting up reader for " << value->GetBranchName() << '\n';
      return false;
   }
   return true;
}

// Analyze the tree "MyTree" in the file passed into the function.
// Returns false in case of errors.
bool analyze(TFile* file) {
   // Create a TTreeReader named "MyTree" from the given TDirectory.
   // The TTreeReader gives access to the TTree to the TTreeReaderValue and
   // TTreeReaderArray objects. It knows the current entry number and knows
   // how to iterate through the TTree.
   TTreeReader reader("MyTree", file);

   // Read a single float value in each tree entries:
   TTreeReaderValue<float> weight(reader, "event.weight");
   if (!CheckValue(weight)) return false;

   // Read a TriggerInfo object from the tree entries:
   TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
   if (!CheckValue(triggerInfo)) return false;

   //Read a vector of Muon objects from the tree entries:
   TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
   if (!CheckValue(muons)) return false;

   //Read the pT for all jets in the tree entry:
   TTreeReaderArray<double> jetPt(reader, "jets.pT");
   if (!CheckValue(jetPt)) return false;

   // Read the taus in the tree entry:
   TTreeReaderArray<Tau> taus(reader, "taus");
   if (!CheckValue(taus)) return false;

   // Now iterate through the TTree entries and fill a histogram.

   TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);

   while (reader.Next()) {

      if (reader.GetEntryStatus() == kEntryValid) {
         std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
      } else {
         switch (reader.GetEntryStatus()) {
         kEntryValid:
            // Handled above.
            break;
         kEntryNotLoaded:
            std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
            break;
         kEntryNoTree:
            std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
            break;
         kEntryNotFound:
            // Can't really happen as TTreeReader::Next() knows when to stop.
            std::cerr << "Error: The entry number doe not exist\n";
            break;
         kEntryChainSetupError:
            std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
            break;
         kEntryChainFileError:
            std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
            break;
         kEntryDictionaryError:
            std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
            break;
         }
         return false;
      }

      // Access the TriggerInfo object as if it's a pointer.
      if (!triggerInfo->hasMuonL1())
         continue;

      // Ditto for the vector<Muon>.
      if (!muons->size())
         continue;

      // Access the jetPt as an array, whether the TTree stores this as
      // a std::vector, std::list, TClonesArray or Jet* C-style array, with
      // fixed or variable array size.
      if (jetPt.GetSize() < 2 || jetPt[0] < 100)
         continue;

      // Access the array of taus.
      if (!taus.IsEmpty()) {
         float currentWeight = *weight;
         for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) {
            // Access a float value - need to dereference as TTreeReaderValue
            // behaves like an iterator
            hist->Fill(taus[iTau].eta(), currentWeight);
         }
      }
   } // TTree entry / event loop
}
~~~
*/

ClassImp(TTreeReader)

using namespace ROOT::Internal;

////////////////////////////////////////////////////////////////////////////////
/// Access data from tree.

TTreeReader::TTreeReader(TTree* tree):
   fTree(tree),
   fDirectory(0),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fTree) {
      Error("TTreeReader", "TTree is NULL!");
   } else {
      Initialize();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Access data from the tree called keyname in the directory (e.g. TFile)
/// dir, or the current directory if dir is NULL. If keyname cannot be
/// found, or if it is not a TTree, IsZombie() will return true.

TTreeReader::TTreeReader(const char* keyname, TDirectory* dir /*= NULL*/):
   fTree(0),
   fDirectory(dir),
   fEntryStatus(kEntryNotLoaded),
   fDirector(0),
   fLastEntry(-1),
   fProxiesSet(kFALSE)
{
   if (!fDirectory) fDirectory = gDirectory;
   fDirectory->GetObject(keyname, fTree);
   Initialize();
}

////////////////////////////////////////////////////////////////////////////////
/// Tell all value readers that the tree reader does not exist anymore.

TTreeReader::~TTreeReader()
{
   for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
           i = fValues.begin(), e = fValues.end(); i != e; ++i) {
      (*i)->MarkTreeReaderUnavailable();
   }
   delete fDirector;
   fProxies.SetOwner();
}

////////////////////////////////////////////////////////////////////////////////
/// Initialization of the director.

void TTreeReader::Initialize()
{
   if (!fTree) {
      MakeZombie();
      fEntryStatus = kEntryNoTree;
   } else {
      fDirector = new ROOT::Internal::TBranchProxyDirector(fTree, -1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Set the range of entries to be processed.
/// If last > first, this call is equivalent to
/// `SetEntry(first); SetLastEntry(last);`. Otherwise `last` is ignored and
/// only `first` is set.
/// \return the EEntryStatus that would be returned by SetEntry(first)

TTreeReader::EEntryStatus TTreeReader::SetEntriesRange(Long64_t first, Long64_t last)
{
   if(last > first)
      fLastEntry = last;
   else
      fLastEntry = -1;
   return SetEntry(first);
}

////////////////////////////////////////////////////////////////////////////////
///Returns the index of the current entry being read

Long64_t TTreeReader::GetCurrentEntry() const {
   if (!fDirector) return 0;
   Long64_t currentTreeEntry = fDirector->GetReadEntry();
   if (fTree->IsA() == TChain::Class() && currentTreeEntry >= 0) {
      return ((TChain*)fTree)->GetChainEntryNumber(currentTreeEntry);
   }
   return currentTreeEntry;
}

////////////////////////////////////////////////////////////////////////////////
/// Load an entry into the tree, return the status of the read.
/// For chains, entry is the global (i.e. not tree-local) entry number, unless
/// `local` is `true`, in which case `entry` specifies the entry number within
/// the current tree. This is needed for instance for TSelector::Process().

TTreeReader::EEntryStatus TTreeReader::SetEntryBase(Long64_t entry, Bool_t local)
{
   if (!fTree) {
      fEntryStatus = kEntryNoTree;
      return fEntryStatus;
   }

   TTree* prevTree = fDirector->GetTree();

   Int_t treeNumInChainBeforeLoad = fTree->GetTreeNumber();

   TTree* treeToCallLoadOn = local ? fTree->GetTree() : fTree;
   Long64_t loadResult = treeToCallLoadOn->LoadTree(entry);

   if (loadResult == -2) {
      fEntryStatus = kEntryNotFound;
      return fEntryStatus;
   }

   if (treeNumInChainBeforeLoad != fTree->GetTreeNumber()) {
      fDirector->SetTree(fTree->GetTree());
   }

   if (!prevTree || fDirector->GetReadEntry() == -1 || !fProxiesSet) {
      // Tell readers we now have a tree
      for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
              i = fValues.begin(); i != fValues.end(); ++i) { // Iterator end changes when parameterized arrays are read
         (*i)->CreateProxy();

         if (!(*i)->GetProxy()){
            fEntryStatus = kEntryDictionaryError;
            return fEntryStatus;
         }
      }
      // If at least one proxy was there and no error occurred, we assume the proxies to be set.
      fProxiesSet = !fValues.empty();
   }
   if (fLastEntry >= 0 && entry >= fLastEntry) {
      fEntryStatus = kEntryLast;
      return fEntryStatus;
   }
   fDirector->SetReadEntry(loadResult);
   fEntryStatus = kEntryValid;
   return fEntryStatus;
}

////////////////////////////////////////////////////////////////////////////////
/// Set (or update) the which tree to reader from. tree can be
/// a TTree or a TChain.

void TTreeReader::SetTree(TTree* tree)
{
   fTree = tree;
   if (fTree) {
      ResetBit(kZombie);
      if (fTree->InheritsFrom(TChain::Class())) {
         SetBit(kBitIsChain);
      }
   }

   if (!fDirector) {
      Initialize();
   }
   else {
      fDirector->SetTree(fTree);
      fDirector->SetReadEntry(-1);
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Add a value reader for this tree.

void TTreeReader::RegisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   fValues.push_back(reader);
}

////////////////////////////////////////////////////////////////////////////////
/// Remove a value reader for this tree.

void TTreeReader::DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader)
{
   std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
      = std::find(fValues.begin(), fValues.end(), reader);
   if (iReader == fValues.end()) {
      Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
      return;
   }
   fValues.erase(iReader);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "DialServer.h"
#include <curl/curl.h>

using namespace std;

enum DIAL_COMMAND{
    COMMAND_LAUNCH,
    COMMAND_STATUS,
    COMMAND_KILL
};

static size_t header_cb(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    if ((size * nmemb) != 0) {
        string newHeader((char*)ptr);
        string *header = static_cast<string*>(userdata);
        header->append(newHeader);
        ATRACE("%s: Adding header: %s", __FUNCTION__, newHeader.c_str());
    }
    return (size * nmemb);
}

static size_t receiveData(void *ptr, size_t size, size_t nmemb, void *userdata)
{
    if ((size * nmemb) != 0) {
        string *body= static_cast<string*>(userdata);
        body->append((char*)ptr);
        ATRACE("%s: Adding to Body: %s", __FUNCTION__, (char*)ptr);
    }
    return (size * nmemb);
}

int DialServer::sendCommand(
        string &url,
        int command,
        string &payload,
        string &responseHeaders,
        string &responseBody )
{
    CURL *curl;
    CURLcode res = CURLE_OK;

    if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
    {
        fprintf(stderr, "curl_global_init() failed\n");
        return 0;
    }

    if ((curl = curl_easy_init()) == NULL)
    {
        fprintf(stderr, "curl_easy_init() failed\n");
        curl_global_cleanup();
        return 0;
    }

    if (command == COMMAND_LAUNCH)
    {
        curl_easy_setopt(curl, CURLOPT_POST, true);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
        if( payload.size() )
        {
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
        }
#ifdef DEBUG
        else ATRACE("Sending empty POST\n");
#endif
    }
    else if (command == COMMAND_KILL)
    {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    ATRACE("Sending %s:%s\n",
        command == COMMAND_LAUNCH ? "LAUNCH" :
            (command == COMMAND_KILL ? "KILL" : "STATUS"),
        url.c_str());

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveData);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody);
    res = curl_easy_perform(curl);

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return (res == CURLE_OK);
}

string DialServer::getIpAddress()
{
    // m_appsUrl=http://192.168.1.103:36269/apps/
    if( m_ipAddr.empty() )
    {
        size_t begin = m_appsUrl.find("//");
        if( begin != m_appsUrl.npos )
        {
            begin += 2; // move to the start of the IP address
            size_t end = m_appsUrl.find(":", begin);
            if( end != m_appsUrl.npos )
            {
                m_ipAddr = m_appsUrl.substr( begin, end-begin );
                ATRACE("IP ADDRESS: %s\n", m_ipAddr.c_str() );
            }
        }
    }
    return m_ipAddr;
}

bool DialServer::getFriendlyName( string& name )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string friendlyName = "<friendlyName>";
        size_t pos;
        if( ( pos = m_ddxml.find( friendlyName ) ) != m_ddxml.npos )
        {
            string friendlyNameEnd = "</friendlyName>";
            size_t end = m_ddxml.find( friendlyNameEnd );
            name = m_ddxml.substr( pos + friendlyName.size(),
                        (end - (pos + friendlyName.size())) );
            ATRACE("***Friendly name=%s***", name.c_str());
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

bool DialServer::getUuid( string& uuid )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string udn = "<UDN>";
        size_t pos;
        if( ( pos = m_ddxml.find( udn ) ) != m_ddxml.npos )
        {
            string udnEnd = "</UDN>";
            size_t end = m_ddxml.find( udnEnd );
            uuid = m_ddxml.substr( pos + udn.size(),
                        (end - (pos + udn.size())) );
            ATRACE("***UUID=%s***", uuid.c_str() );
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

string DialServer::getMacAddress()
{
    return m_macAddr;
}

int  DialServer::getWakeOnLanTimeout()
{
    return m_wakeUpTimeout;
}

int DialServer::launchApplication(
    string &application,
    string &payload,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Launch %s\n", __FUNCTION__, application.c_str());
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_LAUNCH, payload, responseHeaders, responseBody);
    return status;
}

int DialServer::getStatus(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: GetStatus %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_STATUS, emptyPayload, responseHeaders, responseBody );

    if (!status) return 0;
    ATRACE("Body: %s\n", responseBody.c_str());
    unsigned found = responseBody.find("href=");
    if( found != string::npos )
    {
        // The start of href is after href= and the quote
        unsigned href_start = found + 5 + 1;

        // get the body from the start of href to the end, then find
        // the last quote delimiter.
        string tmp = responseBody.substr( href_start );
        unsigned href_end = tmp.find("\"");
        m_stopEndPoint = responseBody.substr( href_start, href_end );
    }
    return 0;
}

int DialServer::stopApplication(
    string &application,
    string &responseHeaders )
{
    ATRACE("%s: Quit %s\n", __FUNCTION__, application.c_str());
    string emptyPayload, responseBody;  // dropping this
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append(application)).append("/"+m_stopEndPoint),
                             COMMAND_KILL, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::getHttpResponseHeader(
    string &responseHeaders,
    string &header,
    string &value )
{
    return 0;
}
<commit_msg>URL append fixes on sendCommand<commit_after>/*
 * Copyright (c) 2014 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "DialServer.h"
#include <curl/curl.h>

using namespace std;

enum DIAL_COMMAND{
    COMMAND_LAUNCH,
    COMMAND_STATUS,
    COMMAND_KILL
};

static size_t header_cb(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    if ((size * nmemb) != 0) {
        string newHeader((char*)ptr);
        string *header = static_cast<string*>(userdata);
        header->append(newHeader);
        ATRACE("%s: Adding header: %s", __FUNCTION__, newHeader.c_str());
    }
    return (size * nmemb);
}

static size_t receiveData(void *ptr, size_t size, size_t nmemb, void *userdata)
{
    if ((size * nmemb) != 0) {
        string *body= static_cast<string*>(userdata);
        body->append((char*)ptr);
        ATRACE("%s: Adding to Body: %s", __FUNCTION__, (char*)ptr);
    }
    return (size * nmemb);
}

int DialServer::sendCommand(
        string &url,
        int command,
        string &payload,
        string &responseHeaders,
        string &responseBody )
{
    CURL *curl;
    CURLcode res = CURLE_OK;

    if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
    {
        fprintf(stderr, "curl_global_init() failed\n");
        return 0;
    }

    if ((curl = curl_easy_init()) == NULL)
    {
        fprintf(stderr, "curl_easy_init() failed\n");
        curl_global_cleanup();
        return 0;
    }

    if (command == COMMAND_LAUNCH)
    {
        curl_easy_setopt(curl, CURLOPT_POST, true);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
        if( payload.size() )
        {
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
        }
#ifdef DEBUG
        else ATRACE("Sending empty POST\n");
#endif
    }
    else if (command == COMMAND_KILL)
    {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    ATRACE("Sending %s:%s\n",
        command == COMMAND_LAUNCH ? "LAUNCH" :
            (command == COMMAND_KILL ? "KILL" : "STATUS"),
        url.c_str());

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveData);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody);
    res = curl_easy_perform(curl);

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return (res == CURLE_OK);
}

string DialServer::getIpAddress()
{
    // m_appsUrl=http://192.168.1.103:36269/apps/
    if( m_ipAddr.empty() )
    {
        size_t begin = m_appsUrl.find("//");
        if( begin != m_appsUrl.npos )
        {
            begin += 2; // move to the start of the IP address
            size_t end = m_appsUrl.find(":", begin);
            if( end != m_appsUrl.npos )
            {
                m_ipAddr = m_appsUrl.substr( begin, end-begin );
                ATRACE("IP ADDRESS: %s\n", m_ipAddr.c_str() );
            }
        }
    }
    return m_ipAddr;
}

bool DialServer::getFriendlyName( string& name )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string friendlyName = "<friendlyName>";
        size_t pos;
        if( ( pos = m_ddxml.find( friendlyName ) ) != m_ddxml.npos )
        {
            string friendlyNameEnd = "</friendlyName>";
            size_t end = m_ddxml.find( friendlyNameEnd );
            name = m_ddxml.substr( pos + friendlyName.size(),
                        (end - (pos + friendlyName.size())) );
            ATRACE("***Friendly name=%s***", name.c_str());
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

bool DialServer::getUuid( string& uuid )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string udn = "<UDN>";
        size_t pos;
        if( ( pos = m_ddxml.find( udn ) ) != m_ddxml.npos )
        {
            string udnEnd = "</UDN>";
            size_t end = m_ddxml.find( udnEnd );
            uuid = m_ddxml.substr( pos + udn.size(),
                        (end - (pos + udn.size())) );
            ATRACE("***UUID=%s***", uuid.c_str() );
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

string DialServer::getMacAddress()
{
    return m_macAddr;
}

int  DialServer::getWakeOnLanTimeout()
{
    return m_wakeUpTimeout;
}

int DialServer::launchApplication(
    string &application,
    string &payload,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Launch %s\n", __FUNCTION__, application.c_str());
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append("/" + application), COMMAND_LAUNCH, payload, responseHeaders, responseBody);
    return status;
}

int DialServer::getStatus(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: GetStatus %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append("/" + application), COMMAND_STATUS, emptyPayload, responseHeaders, responseBody );

    if (!status) return 0;
    //ATRACE("Body: %s\n", responseBody.c_str());
    unsigned found = responseBody.find("href=");
    if( found != string::npos )
    {
        // The start of href is after href= and the quote
        unsigned href_start = found + 5 + 1;

        // get the body from the start of href to the end, then find
        // the last quote delimiter.
        string tmp = responseBody.substr( href_start );
        unsigned href_end = tmp.find("\"");
        m_stopEndPoint = responseBody.substr( href_start, href_end );
    }
    return 0;
}

int DialServer::stopApplication(
    string &application,
    string &responseHeaders )
{
    ATRACE("%s: Quit %s\n", __FUNCTION__, application.c_str());
    string emptyPayload, responseBody;  // dropping this
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append("/" + application)).append("/"+m_stopEndPoint),
                             COMMAND_KILL, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::getHttpResponseHeader(
    string &responseHeaders,
    string &header,
    string &value )
{
    return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * GARGOYLE_PSCAND: Gargoyle Port Scan Detector
 *
 * netfilter queue handling code
 *
 * Copyright (c) 2016 - 2017, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
#include "nf_queue.h"

#include <iostream>
#include <stdlib.h>
#include <sys/select.h>
#include <memory.h>
#include <signal.h>
#include <netinet/in.h>
#include <linux/netfilter.h>

Queue::Queue(const Library& lib, u_int16_t num, PacketHandler& packetHandler) : _packetHandler(packetHandler)
{
	_handle = nfq_create_queue(lib._handle, num, _callback, this);
	if (!_handle)
		std::cout << "Cannot create queue" << std::endl;

	if (nfq_set_mode(_handle, NFQNL_COPY_PACKET, 0xffff) < 0)
	{
		nfq_destroy_queue(_handle);
		std::cout << "Cannot set COPY_PACKET mode" << std::endl;
	}
	//std::cout << "[NF QUEUE] created" << std::endl;
}

Queue::~Queue()
{
	nfq_destroy_queue(_handle);
	//std::cout << "[NF QUEUE] destroyed" << std::endl;
}

int Queue::_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfad, void *data)
{
	Queue* queue = reinterpret_cast<Queue*>(data);
	return queue->_packetHandler.handle_packet(*queue, nfmsg, nfad);
}

void Queue::setVerdict(u_int32_t id, u_int32_t verdict, u_int32_t data_len, const unsigned char *buf)
{
	nfq_set_verdict(_handle, id, verdict, data_len, buf);
}

Library::Library()
{
	_handle = nfq_open();
	if (!_handle)
		std::cout << "Cannot open queue" << std::endl;
	//std::cout << "[NF LIB] - CONSTRUCTOR - created" << std::endl;
}

Library::~Library()
{
	nfq_close(_handle);
	//std::cout << "[NF LIB] - DESTRUCTOR - destroyed" << std::endl;
}

void Library::bind(u_int16_t protocolFamily)
{
	if (nfq_unbind_pf(_handle, protocolFamily) < 0)
		std::cout << "Cannot unbind protocol family" << std::endl;

	if (nfq_bind_pf(_handle, protocolFamily) < 0)
		std::cout << "Cannot bind protocol family" << std::endl;
}

void Library::loop()
{
	// Block INT signals
	{
		sigset_t intmask;
		sigemptyset(&intmask);
		sigaddset(&intmask, SIGINT);
		if (sigprocmask(SIG_BLOCK, &intmask, NULL) == -1)
			std::cout << "Cannot block INT signal" << std::endl;
	}

	// Ignore INT signals
	{
		struct sigaction sa;
		memset(&sa, 0, sizeof(sa));
		sa.sa_flags = 0;
		sa.sa_handler = _sigint;
		sigemptyset(&sa.sa_mask);
		if (sigaction(SIGINT, &sa, NULL) == -1)
			std::cout << "Cannot set INT handler" << std::endl;
	}

	sigset_t emptymask;
	sigemptyset(&emptymask);

	char buf[4096] __attribute__ ((aligned));
	//char buf[4096];
	int fd = nfq_fd(_handle);
	fd_set rfds;

	for (;;)
	{
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		if (pselect(fd+1, &rfds, NULL, NULL, NULL, &emptymask) <= 0)
			break;

		if (!FD_ISSET(fd, &rfds))
			break;

		int rv = recv(fd, buf, sizeof(buf), 0);
		if (rv < 0)
			break;

		nfq_handle_packet(_handle, buf, rv);
	}
}

<commit_msg>introduced use of the TEMP_FAILURE_RETRY macro in order to gracefully handle some netfilter queue related use cases<commit_after>/*****************************************************************************
 *
 * GARGOYLE_PSCAND: Gargoyle Port Scan Detector
 *
 * netfilter queue handling code
 *
 * Copyright (c) 2016 - 2017, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
#include "nf_queue.h"

#include <iostream>

#include <errno.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <linux/netfilter.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>

Queue::Queue(const Library& lib, u_int16_t num, PacketHandler& packetHandler) : _packetHandler(packetHandler)
{
	_handle = nfq_create_queue(lib._handle, num, _callback, this);
	if (!_handle)
		std::cout << "Cannot create queue" << std::endl;

	if (nfq_set_mode(_handle, NFQNL_COPY_PACKET, 0xffff) < 0)
	{
		nfq_destroy_queue(_handle);
		std::cout << "Cannot set COPY_PACKET mode" << std::endl;
	}
	//std::cout << "[NF QUEUE] created" << std::endl;
}

Queue::~Queue()
{
	nfq_destroy_queue(_handle);
	//std::cout << "[NF QUEUE] destroyed" << std::endl;
}

int Queue::_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfad, void *data)
{
	Queue* queue = reinterpret_cast<Queue*>(data);
	return queue->_packetHandler.handle_packet(*queue, nfmsg, nfad);
}

void Queue::setVerdict(u_int32_t id, u_int32_t verdict, u_int32_t data_len, const unsigned char *buf)
{
	nfq_set_verdict(_handle, id, verdict, data_len, buf);
}

Library::Library()
{
	_handle = nfq_open();
	if (!_handle)
		std::cout << "Cannot open queue" << std::endl;
	//std::cout << "[NF LIB] - CONSTRUCTOR - created" << std::endl;
}

Library::~Library()
{
	nfq_close(_handle);
	//std::cout << "[NF LIB] - DESTRUCTOR - destroyed" << std::endl;
}

void Library::bind(u_int16_t protocolFamily)
{
	if (nfq_unbind_pf(_handle, protocolFamily) < 0)
		std::cout << "Cannot unbind protocol family" << std::endl;

	if (nfq_bind_pf(_handle, protocolFamily) < 0)
		std::cout << "Cannot bind protocol family" << std::endl;
}

void Library::loop()
{
	// Block INT signals
	{
		sigset_t intmask;
		sigemptyset(&intmask);
		sigaddset(&intmask, SIGINT);
		if (sigprocmask(SIG_BLOCK, &intmask, NULL) == -1)
			std::cout << "Cannot block INT signal" << std::endl;
	}

	// Ignore INT signals
	{
		struct sigaction sa;
		memset(&sa, 0, sizeof(sa));
		sa.sa_flags = 0;
		sa.sa_handler = _sigint;
		sigemptyset(&sa.sa_mask);
		if (sigaction(SIGINT, &sa, NULL) == -1)
			std::cout << "Cannot set INT handler" << std::endl;
	}

	sigset_t emptymask;
	sigemptyset(&emptymask);

	char buf[4096] __attribute__ ((aligned));
	//char buf[4096];
	int fd = nfq_fd(_handle);
	fd_set rfds;

	for (;;)
	{
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		if (pselect(fd+1, &rfds, NULL, NULL, NULL, &emptymask) <= 0) {
			//std::cout << "BREAK @ pselect" << std::endl;
			//break;
			continue;
		}

		if (!FD_ISSET(fd, &rfds)) {
			//std::cout << "BREAK @ FD_ISSET" << std::endl;
			//break;
			continue;
		}

		//int rv = recv(fd, buf, sizeof(buf), 0);
		int rv = TEMP_FAILURE_RETRY(recv(fd, buf, sizeof(buf), 0));
		if (rv < 0) {
			//std::cout << "BREAK @ recv - returned - " << rv << std::endl;
			//break;
			continue;
		}

		nfq_handle_packet(_handle, buf, rv);
	}
}

<|endoftext|>