<commit_before>/*
 * ViewerHistory.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "ViewerHistory.hpp"

#include <boost/format.hpp>
#include <boost/foreach.hpp>

#include <core/SafeConvert.hpp>
#include <core/FileSerializer.hpp>

#include <session/SessionModuleContext.hpp>

using namespace core;

namespace session {
namespace modules {
namespace viewer {

ViewerHistory& viewerHistory()
{
   static ViewerHistory instance;
   return instance;
}

ViewerHistory::ViewerHistory()
   : currentIndex_(-1)
{
   entries_.set_capacity(20);
}

void ViewerHistory::add(const module_context::ViewerHistoryEntry& entry)
{
   entries_.push_back(entry);
   currentIndex_ = entries_.size() - 1;
}

void ViewerHistory::clear()
{
   currentIndex_ = -1;
   entries_.clear();
}

module_context::ViewerHistoryEntry ViewerHistory::current() const
{
   if (currentIndex_ == -1)
      return module_context::ViewerHistoryEntry();
   else
      return entries_[currentIndex_];
}

void ViewerHistory::clearCurrent()
{
   if (currentIndex_ != -1)
   {
      entries_.erase(entries_.begin() + currentIndex_);
      if (entries_.size() > 0)
         currentIndex_ = std::max(0, currentIndex_ - 1);
      else
         currentIndex_ = -1;
   }
}

bool ViewerHistory::hasNext() const
{
   return currentIndex_ != -1 && currentIndex_ < (entries_.size() - 1);
}

module_context::ViewerHistoryEntry ViewerHistory::goForward()
{
   if (hasNext())
      return entries_[++currentIndex_];
   else
      return module_context::ViewerHistoryEntry();
}

bool ViewerHistory::hasPrevious() const
{
   return entries_.size() > 0 && currentIndex_ > 0;
}

module_context::ViewerHistoryEntry ViewerHistory::goBack()
{
   if (hasPrevious())
      return entries_[--currentIndex_];
   else
      return module_context::ViewerHistoryEntry();
}

namespace {

FilePath historyEntriesPath(const core::FilePath& serializationPath)
{
   return serializationPath.complete("history_entries");
}

FilePath currentIndexPath(const core::FilePath& serializationPath)
{
   return serializationPath.complete("current_index");
}

std::string historyEntryToString(const module_context::ViewerHistoryEntry& entry)
{
   return entry.sessionTempPath();
}

ReadCollectionAction historyEntryFromString(
         const std::string& url, module_context::ViewerHistoryEntry* pEntry)
{
   *pEntry = module_context::ViewerHistoryEntry(url);
   return ReadCollectionAddLine;
}

} // anonymous namespace

void ViewerHistory::saveTo(const core::FilePath& serializationPath) const
{
   // blow away any existing serialization data
   Error error = serializationPath.removeIfExists();
   if (error)
      LOG_ERROR(error);

   // skip if there is no current index
   if (currentIndex_ == -1)
      return;

   // ensure the directory
   error = serializationPath.ensureDirectory();
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // save the current index
   std::string currentIndex = safe_convert::numberToString(currentIndex_);
   error = core::writeStringToFile(currentIndexPath(serializationPath),
                                   currentIndex);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // save the list of entries
   using module_context::ViewerHistoryEntry;
   error = writeCollectionToFile<boost::circular_buffer<ViewerHistoryEntry> >(
                                         historyEntriesPath(serializationPath),
                                         entries_,
                                         historyEntryToString);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // copy the files
   FilePath tempDir = module_context::tempDir();
   for (std::size_t i = 0; i<entries_.size(); i++)
   {
      ViewerHistoryEntry entry = entries_.at(i);
      Error error = entry.copy(tempDir, serializationPath);
      if (error)
         LOG_ERROR(error);
   }
}

void ViewerHistory::restoreFrom(const core::FilePath& serializationPath)
{
   // skip if the directory doesn't exist
   if (!serializationPath.exists())
      return;

   // clear existing
   currentIndex_ = -1;
   entries_.clear();

   // read the current index (bail if we can't find one)
   std::string currentIndex;
   Error error = core::readStringFromFile(currentIndexPath(serializationPath),
                                          &currentIndex);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }
   currentIndex_ = safe_convert::stringTo<int>(currentIndex, -1);
   if (currentIndex_ == -1)
      return;

   // read the entries
   using module_context::ViewerHistoryEntry;
   error = readCollectionFromFile<boost::circular_buffer<ViewerHistoryEntry> >(
                                         historyEntriesPath(serializationPath),
                                         &entries_,
                                         historyEntryFromString);
   if (error)
   {
      LOG_ERROR(error);
      entries_.clear();
      currentIndex_ = -1;
      return;
   }

   // copy the files to the session temp dir
   FilePath tempDir = module_context::tempDir();
   BOOST_FOREACH(const ViewerHistoryEntry& entry, entries_)
   {
      Error error = entry.copy(serializationPath, tempDir);
      if (error)
         LOG_ERROR(error);
   }
}

} // namespace viewer
} // namespace modules

namespace module_context {

std::string ViewerHistoryEntry::url() const
{
   if (session::options().programMode() == kSessionProgramModeDesktop)
   {
      boost::format fmt("http://localhost:%1%/session/%2%");
      return boost::str(fmt % rLocalHelpPort() % sessionTempPath_);
   }
   else
   {
      boost::format fmt("session/%1%");
      return boost::str(fmt % sessionTempPath_);
   }
}

core::Error ViewerHistoryEntry::copy(
             const core::FilePath& sourceDir,
             const core::FilePath& destinationDir) const
{
   // if this is a standalone file in the root of the temp dir then
   // just copy the file
   FilePath entryPath = sourceDir.childPath(sessionTempPath_);
   if (entryPath.parent().isEquivalentTo(sourceDir))
   {
      return entryPath.copy(destinationDir.childPath(entryPath.filename()));
   }

   // otherwise copy the entire directory
   else
   {
      FilePath parentDir = entryPath.parent();
      return module_context::recursiveCopyDirectory(parentDir, destinationDir);
   }
}

void addViewerHistoryEntry(const ViewerHistoryEntry& entry)
{
   modules::viewer::viewerHistory().add(entry);
}

} // namespace module_context

} // namesapce session

<commit_msg>check for viewer history index before reading<commit_after>/*
 * ViewerHistory.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "ViewerHistory.hpp"

#include <boost/format.hpp>
#include <boost/foreach.hpp>

#include <core/SafeConvert.hpp>
#include <core/FileSerializer.hpp>

#include <session/SessionModuleContext.hpp>

using namespace core;

namespace session {
namespace modules {
namespace viewer {

ViewerHistory& viewerHistory()
{
   static ViewerHistory instance;
   return instance;
}

ViewerHistory::ViewerHistory()
   : currentIndex_(-1)
{
   entries_.set_capacity(20);
}

void ViewerHistory::add(const module_context::ViewerHistoryEntry& entry)
{
   entries_.push_back(entry);
   currentIndex_ = entries_.size() - 1;
}

void ViewerHistory::clear()
{
   currentIndex_ = -1;
   entries_.clear();
}

module_context::ViewerHistoryEntry ViewerHistory::current() const
{
   if (currentIndex_ == -1)
      return module_context::ViewerHistoryEntry();
   else
      return entries_[currentIndex_];
}

void ViewerHistory::clearCurrent()
{
   if (currentIndex_ != -1)
   {
      entries_.erase(entries_.begin() + currentIndex_);
      if (entries_.size() > 0)
         currentIndex_ = std::max(0, currentIndex_ - 1);
      else
         currentIndex_ = -1;
   }
}

bool ViewerHistory::hasNext() const
{
   return currentIndex_ != -1 && currentIndex_ < (entries_.size() - 1);
}

module_context::ViewerHistoryEntry ViewerHistory::goForward()
{
   if (hasNext())
      return entries_[++currentIndex_];
   else
      return module_context::ViewerHistoryEntry();
}

bool ViewerHistory::hasPrevious() const
{
   return entries_.size() > 0 && currentIndex_ > 0;
}

module_context::ViewerHistoryEntry ViewerHistory::goBack()
{
   if (hasPrevious())
      return entries_[--currentIndex_];
   else
      return module_context::ViewerHistoryEntry();
}

namespace {

FilePath historyEntriesPath(const core::FilePath& serializationPath)
{
   return serializationPath.complete("history_entries");
}

FilePath currentIndexPath(const core::FilePath& serializationPath)
{
   return serializationPath.complete("current_index");
}

std::string historyEntryToString(const module_context::ViewerHistoryEntry& entry)
{
   return entry.sessionTempPath();
}

ReadCollectionAction historyEntryFromString(
         const std::string& url, module_context::ViewerHistoryEntry* pEntry)
{
   *pEntry = module_context::ViewerHistoryEntry(url);
   return ReadCollectionAddLine;
}

} // anonymous namespace

void ViewerHistory::saveTo(const core::FilePath& serializationPath) const
{
   // blow away any existing serialization data
   Error error = serializationPath.removeIfExists();
   if (error)
      LOG_ERROR(error);

   // skip if there is no current index
   if (currentIndex_ == -1)
      return;

   // ensure the directory
   error = serializationPath.ensureDirectory();
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // save the current index
   std::string currentIndex = safe_convert::numberToString(currentIndex_);
   error = core::writeStringToFile(currentIndexPath(serializationPath),
                                   currentIndex);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // save the list of entries
   using module_context::ViewerHistoryEntry;
   error = writeCollectionToFile<boost::circular_buffer<ViewerHistoryEntry> >(
                                         historyEntriesPath(serializationPath),
                                         entries_,
                                         historyEntryToString);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }

   // copy the files
   FilePath tempDir = module_context::tempDir();
   for (std::size_t i = 0; i<entries_.size(); i++)
   {
      ViewerHistoryEntry entry = entries_.at(i);
      Error error = entry.copy(tempDir, serializationPath);
      if (error)
         LOG_ERROR(error);
   }
}

void ViewerHistory::restoreFrom(const core::FilePath& serializationPath)
{
   // skip if the directory doesn't exist
   if (!serializationPath.exists())
      return;

   // clear existing
   currentIndex_ = -1;
   entries_.clear();

   // check if we have an index path (bail if we can't find one)
   FilePath indexPath = currentIndexPath(serializationPath);
   if (!indexPath.exists())
      return;

   // read the index
   std::string currentIndex;
   Error error = core::readStringFromFile(indexPath, &currentIndex);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }
   currentIndex_ = safe_convert::stringTo<int>(currentIndex, -1);
   if (currentIndex_ == -1)
      return;

   // read the entries
   using module_context::ViewerHistoryEntry;
   error = readCollectionFromFile<boost::circular_buffer<ViewerHistoryEntry> >(
                                         historyEntriesPath(serializationPath),
                                         &entries_,
                                         historyEntryFromString);
   if (error)
   {
      LOG_ERROR(error);
      entries_.clear();
      currentIndex_ = -1;
      return;
   }

   // copy the files to the session temp dir
   FilePath tempDir = module_context::tempDir();
   BOOST_FOREACH(const ViewerHistoryEntry& entry, entries_)
   {
      Error error = entry.copy(serializationPath, tempDir);
      if (error)
         LOG_ERROR(error);
   }
}

} // namespace viewer
} // namespace modules

namespace module_context {

std::string ViewerHistoryEntry::url() const
{
   if (session::options().programMode() == kSessionProgramModeDesktop)
   {
      boost::format fmt("http://localhost:%1%/session/%2%");
      return boost::str(fmt % rLocalHelpPort() % sessionTempPath_);
   }
   else
   {
      boost::format fmt("session/%1%");
      return boost::str(fmt % sessionTempPath_);
   }
}

core::Error ViewerHistoryEntry::copy(
             const core::FilePath& sourceDir,
             const core::FilePath& destinationDir) const
{
   // if this is a standalone file in the root of the temp dir then
   // just copy the file
   FilePath entryPath = sourceDir.childPath(sessionTempPath_);
   if (entryPath.parent().isEquivalentTo(sourceDir))
   {
      return entryPath.copy(destinationDir.childPath(entryPath.filename()));
   }

   // otherwise copy the entire directory
   else
   {
      FilePath parentDir = entryPath.parent();
      return module_context::recursiveCopyDirectory(parentDir, destinationDir);
   }
}

void addViewerHistoryEntry(const ViewerHistoryEntry& entry)
{
   modules::viewer::viewerHistory().add(entry);
}

} // namespace module_context

} // namesapce session

<|endoftext|>


<commit_before>/**
 * \file Graph.cpp
 * \brief Graphs Class
 */

#include "Graph.h"

Graph::Graph(wxPanel* panel, char* name, char* table, int device_id, char* col) {
    /**
    *   Constructor for the Main frame.
    */
	wxFont windowFont(11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);

    window = new mpWindow(panel, -1, wxPoint(0,0), wxSize(1,1), wxSUNKEN_BORDER);

    Plot data = GetData();

    string y_label = wxT("Altitude");
    string x_label = wxT(name);

	// Create a mpFXYVector layer
	mpFXYVector* vectorLayer = new mpFXYVector(_(""));
	vectorLayer->SetData(data.altitude, data.data);
	vectorLayer->SetContinuity(true);
	wxPen vectorpen(*wxBLUE, 2, wxSOLID);
	vectorLayer->SetPen(vectorpen);
	vectorLayer->SetDrawOutsideMargins(false);

    mpScaleX* xaxis = new mpScaleX(x_label, mpALIGN_BOTTOM, true, mpX_NORMAL);
    mpScaleY* yaxis = new mpScaleY(y_label, mpALIGN_LEFT, true);
    xaxis->SetFont(windowFont);
    yaxis->SetFont(windowFont);
    xaxis->SetDrawOutsideMargins(false);
    yaxis->SetDrawOutsideMargins(false);
	xaxis->SetLabelFormat(wxT("%.1f"));
	yaxis->SetLabelFormat(wxT("%.1f"));
    window->SetMargins(30, 30, 50, 100);
    window->AddLayer(     xaxis );
    window->AddLayer(     yaxis );
	window->AddLayer(     vectorLayer );
    window->AddLayer(     new mpText(y_label + wxT(" vs ") + x_label, 60, 5) );
    mpInfoLegend* leg;
    window->AddLayer( leg = new mpInfoLegend(wxRect(200,20,40,40), wxTRANSPARENT_BRUSH)); //&hatch2));
    leg->SetVisible(true);

    window->Fit();
}

Graph::~Graph() {
    /**
    *   Destructor for the Main form.
    */
}

Plot Graph::GetData() {
    return DB_getPlotData(db_table,db_col,deviceId);
}
<commit_msg>- constructor now properly sets attributes<commit_after>/**
 * \file Graph.cpp
 * \brief Graphs Class
 */

#include "Graph.h"

Graph::Graph(wxPanel* panel, char* name, char* table, int device_id, char* col) {
    /**
    *   Constructor for the Main frame.
    */
	wxFont windowFont(11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
    window = new mpWindow(panel, -1, wxPoint(0,0), wxSize(1,1), wxSUNKEN_BORDER);

    this->name = name;
    this->db_table = table;
    this->db_col = col;
    this->deviceId = device_id;

    Plot data = GetData();

    string y_label = wxT("Altitude");
    string x_label = wxT(name);

	// Create a mpFXYVector layer
	mpFXYVector* vectorLayer = new mpFXYVector(_(""));
	vectorLayer->SetData(data.altitude, data.data);
	vectorLayer->SetContinuity(true);
	wxPen vectorpen(*wxBLUE, 2, wxSOLID);
	vectorLayer->SetPen(vectorpen);
	vectorLayer->SetDrawOutsideMargins(false);

    mpScaleX* xaxis = new mpScaleX(x_label, mpALIGN_BOTTOM, true, mpX_NORMAL);
    mpScaleY* yaxis = new mpScaleY(y_label, mpALIGN_LEFT, true);
    xaxis->SetFont(windowFont);
    yaxis->SetFont(windowFont);
    xaxis->SetDrawOutsideMargins(false);
    yaxis->SetDrawOutsideMargins(false);
	xaxis->SetLabelFormat(wxT("%.1f"));
	yaxis->SetLabelFormat(wxT("%.1f"));
    window->SetMargins(30, 30, 50, 100);
    window->AddLayer(     xaxis );
    window->AddLayer(     yaxis );
	window->AddLayer(     vectorLayer );
    window->AddLayer(     new mpText(y_label + wxT(" vs ") + x_label, 60, 5) );
    mpInfoLegend* leg;
    window->AddLayer( leg = new mpInfoLegend(wxRect(200,20,40,40), wxTRANSPARENT_BRUSH)); //&hatch2));
    leg->SetVisible(true);

    window->Fit();
}

Graph::~Graph() {
    /**
    *   Destructor for the Main form.
    */
}

Plot Graph::GetData() {
    return DB_getPlotData(db_table,db_col,deviceId);
}
<|endoftext|>


<commit_before>#include <legui/Label.h>
#include <legui/Config.h>
#include <legui/FontManagerAbstract.h>

namespace legui
{
    Label::Label(Container *parent, const sf::String &text, FontStyle style)
        : Widget(parent)
    {
        m_text = new sf::Text();
        m_string = text;
        this->setStyle(style);
    }
    Label::~Label()
    {
        delete m_text;
    }

    void Label::setStyle(FontStyle style)
    {
        FontStyleUtils::setStyle(m_text, style);
        this->updateSize();
    }
    void Label::setBoundingBox(const sf::FloatRect &box)
    {
        Widget::setBoundingBox(box);

        if(Config::getBool("LABEL_PIXELPERFECT_POSITION"))
            m_text->setPosition(sf::Vector2f((int) box.left, (int) box.top));
        else
            m_text->setPosition(sf::Vector2f(box.left, box.top));
    }
    void Label::updateSize()
    {
        Widget::updateSize();

        if(Config::getBool("LABEL_RECT_BORDER"))
        {
            for(std::size_t i = 0; i < m_text->getString().getSize(); ++i)
            {
                sf::String currentlyVisible("");
                if(m_text->findCharacterPos(i).x > m_boundingBox.left + m_boundingBox.width)
                {
                    m_text->setString(currentlyVisible);
                    continue;
                }
                currentlyVisible += m_text->getString()[i];
            }
        }
        m_boundingBox.width = m_text->getLocalBounds().width;
        m_boundingBox.height = m_text->getLocalBounds().height;
    }
    void Label::draw(sf::RenderTarget &target, sf::RenderStates states) const
    {
        target.draw(*m_text, states);
    }
    void Label::setCharacterSize(unsigned int size)
    {
        m_text->setCharacterSize(size);
        this->updateSize();
    }
    void Label::setFont(const sf::Font &font)
    {
        m_text->setFont(font);
        this->updateSize();
    }
    void Label::setString(const sf::String &text)
    {
        m_text->setString(text);
        m_string = text;
        this->updateSize();
    }
    void Label::setFontStyle(sf::Text::Style style)
    {
        m_text->setStyle(style);
        this->updateSize();
    }
    const sf::String& Label::getVisibleString()
    {
        return m_text->getString();
    }
    const sf::String& Label::getString()
    {
        return m_string;
    }
    const sf::Font* Label::getFont()
    {
        return m_text->getFont();
    }
    sf::Text::Style Label::getFontStyle()
    {
        return static_cast<sf::Text::Style>(m_text->getStyle());
    }
    FontStyle Label::getStyle()
    {
        return m_style;
    }
    unsigned int Label::getCharacterSize()
    {
        return m_text->getCharacterSize();
    }
}
<commit_msg>Fixed the constructor of the label to use the given string.<commit_after>#include <legui/Label.h>
#include <legui/Config.h>
#include <legui/FontManagerAbstract.h>

namespace legui
{
    Label::Label(Container *parent, const sf::String &text, FontStyle style)
        : Widget(parent)
    {
        m_text = new sf::Text();
        this->setString(text);
        this->setStyle(style);
    }
    Label::~Label()
    {
        delete m_text;
    }

    void Label::setStyle(FontStyle style)
    {
        FontStyleUtils::setStyle(m_text, style);
        this->updateSize();
    }
    void Label::setBoundingBox(const sf::FloatRect &box)
    {
        Widget::setBoundingBox(box);

        if(Config::getBool("LABEL_PIXELPERFECT_POSITION"))
            m_text->setPosition(sf::Vector2f((int) box.left, (int) box.top));
        else
            m_text->setPosition(sf::Vector2f(box.left, box.top));
    }
    void Label::updateSize()
    {
        Widget::updateSize();

        if(Config::getBool("LABEL_RECT_BORDER"))
        {
            for(std::size_t i = 0; i < m_text->getString().getSize(); ++i)
            {
                sf::String currentlyVisible("");
                if(m_text->findCharacterPos(i).x > m_boundingBox.left + m_boundingBox.width)
                {
                    m_text->setString(currentlyVisible);
                    continue;
                }
                currentlyVisible += m_text->getString()[i];
            }
        }
        m_boundingBox.width = m_text->getLocalBounds().width;
        m_boundingBox.height = m_text->getLocalBounds().height;
    }
    void Label::draw(sf::RenderTarget &target, sf::RenderStates states) const
    {
        target.draw(*m_text, states);
    }
    void Label::setCharacterSize(unsigned int size)
    {
        m_text->setCharacterSize(size);
        this->updateSize();
    }
    void Label::setFont(const sf::Font &font)
    {
        m_text->setFont(font);
        this->updateSize();
    }
    void Label::setString(const sf::String &text)
    {
        m_text->setString(text);
        m_string = text;
        this->updateSize();
    }
    void Label::setFontStyle(sf::Text::Style style)
    {
        m_text->setStyle(style);
        this->updateSize();
    }
    const sf::String& Label::getVisibleString()
    {
        return m_text->getString();
    }
    const sf::String& Label::getString()
    {
        return m_string;
    }
    const sf::Font* Label::getFont()
    {
        return m_text->getFont();
    }
    sf::Text::Style Label::getFontStyle()
    {
        return static_cast<sf::Text::Style>(m_text->getStyle());
    }
    FontStyle Label::getStyle()
    {
        return m_style;
    }
    unsigned int Label::getCharacterSize()
    {
        return m_text->getCharacterSize();
    }
}
<|endoftext|>


<commit_before>#pragma once
#include <algorithm>
#include <vector>

#include "range/integer_range.hpp"

template<typename T>
constexpr IntegerRange<T> range(const T to) {
	return IntegerRange<T>(0, to);
}

template<typename T>
constexpr IntegerRange<T> range(const T from, const T to) {
	return IntegerRange<T>(from, to);
}

template<typename T>
constexpr IntegerRange<T> inclusiveRange(const T to) {
	return IntegerRange<T>(0, to + 1);
}

template<typename T>
constexpr IntegerRange<T> inclusiveRange(const T from, const T to) {
	return IntegerRange<T>(from, to + 1);
}

template<typename T>
constexpr ReversedIntegerRange<T> downrange(const T from) {
	return ReversedIntegerRange<T>(from, 0);
}

template<typename T>
constexpr ReversedIntegerRange<T> downrange(const T from, const T to) {
	return ReversedIntegerRange<T>(from, to);
}

template<typename T>
constexpr ReversedIntegerRange<T> inclusiveDownrange(const T from) {
	return ReversedIntegerRange<T>(from + 1, 0);
}

template<typename T>
constexpr ReversedIntegerRange<T> inclusiveDownrange(const T from, const T to) {
	return ReversedIntegerRange<T>(from + 1, to);
}

template<typename R>
void sort(R& range) {
	std::sort(range.begin(), range.end());
}

template<typename R, typename Comp>
void sort(R& range, Comp comp) {
	std::sort(range.begin(), range.end(), comp);
}

template<typename R>
void reverse(R& range) {
	std::reverse(range.begin(), range.end());
}

template<typename R, typename T>
auto lower_bound(const R& range, const T& value) -> decltype(range.begin()) {
	return std::lower_bound(range.begin(), range.end(), value);
}

template<typename R, typename T, typename Comp>
auto lower_bound(const R& range, const T& value, Comp comp) -> decltype(range.begin()) {
	return std::lower_bound(range.begin(), range.end(), value, comp);
}

template<typename R, typename T>
auto upper_bound(const R& range, const T& value) -> decltype(range.begin()) {
	return std::upper_bound(range.begin(), range.end(), value);
}

template<typename R, typename T, typename Comp>
auto upper_bound(const R& range, const T& value, Comp comp) -> decltype(range.begin()) {
	return std::upper_bound(range.begin(), range.end(), value, comp);
}

template<typename R>
auto min_element(const R& range) -> decltype(range.begin()) {
	return std::min_element(range.begin(), range.end());
}

template<typename R>
auto max_element(const R& range) -> decltype(range.begin()) {
	return std::max_element(range.begin(), range.end());
}

template<typename R>
bool next_permutation(R& range) {
	return std::next_permutation(range.begin(), range.end());
}

template<typename T>
void unique(std::vector<T>& range) {
	range.erase(std::unique(range.begin(), range.end()), range.end());
}

template<typename R>
R sorted(R range) {
	sort(range);
	return range;
}

template<typename R, typename Comp>
R sorted(R range, Comp comp) {
	sort(range, comp);
	return range;
}

template<typename R>
R reversed(R range) {
	reverse(range);
	return range;
}
<commit_msg>Added dedup() method to ranges/ library.<commit_after>#pragma once
#include <algorithm>
#include <vector>

#include "range/integer_range.hpp"

template<typename T>
constexpr IntegerRange<T> range(const T to) {
	return IntegerRange<T>(0, to);
}

template<typename T>
constexpr IntegerRange<T> range(const T from, const T to) {
	return IntegerRange<T>(from, to);
}

template<typename T>
constexpr IntegerRange<T> inclusiveRange(const T to) {
	return IntegerRange<T>(0, to + 1);
}

template<typename T>
constexpr IntegerRange<T> inclusiveRange(const T from, const T to) {
	return IntegerRange<T>(from, to + 1);
}

template<typename T>
constexpr ReversedIntegerRange<T> downrange(const T from) {
	return ReversedIntegerRange<T>(from, 0);
}

template<typename T>
constexpr ReversedIntegerRange<T> downrange(const T from, const T to) {
	return ReversedIntegerRange<T>(from, to);
}

template<typename T>
constexpr ReversedIntegerRange<T> inclusiveDownrange(const T from) {
	return ReversedIntegerRange<T>(from + 1, 0);
}

template<typename T>
constexpr ReversedIntegerRange<T> inclusiveDownrange(const T from, const T to) {
	return ReversedIntegerRange<T>(from + 1, to);
}

template<typename R>
void sort(R& range) {
	std::sort(range.begin(), range.end());
}

template<typename R, typename Comp>
void sort(R& range, Comp comp) {
	std::sort(range.begin(), range.end(), comp);
}

template<typename R>
void reverse(R& range) {
	std::reverse(range.begin(), range.end());
}

template<typename R, typename T>
auto lower_bound(const R& range, const T& value) -> decltype(range.begin()) {
	return std::lower_bound(range.begin(), range.end(), value);
}

template<typename R, typename T, typename Comp>
auto lower_bound(const R& range, const T& value, Comp comp) -> decltype(range.begin()) {
	return std::lower_bound(range.begin(), range.end(), value, comp);
}

template<typename R, typename T>
auto upper_bound(const R& range, const T& value) -> decltype(range.begin()) {
	return std::upper_bound(range.begin(), range.end(), value);
}

template<typename R, typename T, typename Comp>
auto upper_bound(const R& range, const T& value, Comp comp) -> decltype(range.begin()) {
	return std::upper_bound(range.begin(), range.end(), value, comp);
}

template<typename R>
auto min_element(const R& range) -> decltype(range.begin()) {
	return std::min_element(range.begin(), range.end());
}

template<typename R>
auto max_element(const R& range) -> decltype(range.begin()) {
	return std::max_element(range.begin(), range.end());
}

template<typename R>
bool next_permutation(R& range) {
	return std::next_permutation(range.begin(), range.end());
}

template<typename T>
void unique(std::vector<T>& range) {
	range.erase(std::unique(range.begin(), range.end()), range.end());
}

template<typename T>
void dedup(std::vector<T>& range) {
	sort(range);
	unique(range);
}

template<typename R>
R sorted(R range) {
	sort(range);
	return range;
}

template<typename R, typename Comp>
R sorted(R range, Comp comp) {
	sort(range, comp);
	return range;
}

template<typename R>
R reversed(R range) {
	reverse(range);
	return range;
}
<|endoftext|>


<commit_before>

#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
#include "protocol.h"
#include "spork.h"
#include "main.h"
#include "masternode-budget.h"
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;

class CSporkMessage;
class CSporkManager;

CSporkManager sporkManager;

std::map<uint256, CSporkMessage> mapSporks;
std::map<int, CSporkMessage> mapSporksActive;

void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if(fLiteMode) return; //disable all darksend/masternode related functionality

    if (strCommand == "spork")
    {
        //LogPrintf("ProcessSpork::spork\n");
        CDataStream vMsg(vRecv);
        CSporkMessage spork;
        vRecv >> spork;

        if(chainActive.Tip() == NULL) return;

        uint256 hash = spork.GetHash();
        if(mapSporksActive.count(spork.nSporkID)) {
            if(mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned){
                if(fDebug) LogPrintf("spork - seen %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
                return;
            } else {
                if(fDebug) LogPrintf("spork - got updated spork %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
            }
        }

        LogPrintf("spork - new %s ID %d Time %d bestHeight %d\n", hash.ToString(), spork.nSporkID, spork.nValue, chainActive.Tip()->nHeight);

        if(!sporkManager.CheckSignature(spork)){
            LogPrintf("spork - invalid signature\n");
            Misbehaving(pfrom->GetId(), 100);
            return;
        }

        mapSporks[hash] = spork;
        mapSporksActive[spork.nSporkID] = spork;
        sporkManager.Relay(spork);

        //does a task if needed
        ExecuteSpork(spork.nSporkID, spork.nValue);
    }
    if (strCommand == "getsporks")
    {
        std::map<int, CSporkMessage>::iterator it = mapSporksActive.begin();

        while(it != mapSporksActive.end()) {
            pfrom->PushMessage("spork", it->second);
            it++;
        }
    }

}

// grab the spork, otherwise say it's off
bool IsSporkActive(int nSporkID)
{
    int64_t r = -1;

    if(mapSporksActive.count(nSporkID)){
        r = mapSporksActive[nSporkID].nValue;
    } else {
        if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
        if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
        if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
        if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING_DEFAULT;
        if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
        if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
        if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
        if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;

        if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
    }
    if(r == -1) r = 4070908800; //return 2099-1-1 by default

    return r < GetTime();
}

// grab the value of the spork on the network, or the default
int GetSporkValue(int nSporkID)
{
    int r = 0;

    if(mapSporksActive.count(nSporkID)){
        r = mapSporksActive[nSporkID].nValue;
    } else {
        if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
        if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
        if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
        if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING_DEFAULT;
        if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
        if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
        if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
        if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;

        if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
    }

    return r;
}

void ExecuteSpork(int nSporkID, int nValue)
{
    if(nSporkID == SPORK_11_RESET_BUDGET && nValue == 1){
        budget.Clear();
    }

    //correct fork via spork technology
    if(nSporkID == SPORK_12_RECONSIDER_BLOCKS && nValue > 0) {
        LogPrintf("Spork::ExecuteSpork -- Reconsider Last %d Blocks\n", nValue);

        ReprocessBlocks(nValue);
    }
}

void ReprocessBlocks(int nBlocks)
{
    std::map<uint256, int64_t>::iterator it = mapRejectedBlocks.begin();
    while(it != mapRejectedBlocks.end()){
        //use a window twice as large as is usual for the nBlocks we want to reset
        if((*it).second  > GetTime() - (nBlocks*60*5)) {
            BlockMap::iterator mi = mapBlockIndex.find((*it).first);
            if (mi != mapBlockIndex.end() && (*mi).second) {
                LOCK(cs_main);

                CBlockIndex* pindex = (*mi).second;
                LogPrintf("ReprocessBlocks - %s\n", (*it).first.ToString());

                CValidationState state;
                ReconsiderBlock(state, pindex);
            }
        }
        ++it;
    }

    CValidationState state;
    {
        LOCK(cs_main);
        DisconnectBlocksAndReprocess(nBlocks);
    }

    if (state.IsValid()) {
        ActivateBestChain(state);
    }
}

bool CSporkManager::CheckSignature(CSporkMessage& spork)
{
    //note: need to investigate why this is failing
    std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);
    CPubKey pubkey(ParseHex(Params().SporkKey()));

    std::string errorMessage = "";
    if(!darkSendSigner.VerifyMessage(pubkey, spork.vchSig, strMessage, errorMessage)){
        return false;
    }

    return true;
}

bool CSporkManager::Sign(CSporkMessage& spork)
{
    std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);

    CKey key2;
    CPubKey pubkey2;
    std::string errorMessage = "";

    if(!darkSendSigner.SetKey(strMasterPrivKey, errorMessage, key2, pubkey2))
    {
        LogPrintf("CMasternodePayments::Sign - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage);
        return false;
    }

    if(!darkSendSigner.SignMessage(strMessage, errorMessage, spork.vchSig, key2)) {
        LogPrintf("CMasternodePayments::Sign - Sign message failed");
        return false;
    }

    if(!darkSendSigner.VerifyMessage(pubkey2, spork.vchSig, strMessage, errorMessage)) {
        LogPrintf("CMasternodePayments::Sign - Verify message failed");
        return false;
    }

    return true;
}

bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue)
{

    CSporkMessage msg;
    msg.nSporkID = nSporkID;
    msg.nValue = nValue;
    msg.nTimeSigned = GetTime();

    if(Sign(msg)){
        Relay(msg);
        mapSporks[msg.GetHash()] = msg;
        mapSporksActive[nSporkID] = msg;
        return true;
    }

    return false;
}

void CSporkManager::Relay(CSporkMessage& msg)
{
    CInv inv(MSG_SPORK, msg.GetHash());
    RelayInv(inv);
}

bool CSporkManager::SetPrivKey(std::string strPrivKey)
{
    CSporkMessage msg;

    // Test signing successful, proceed
    strMasterPrivKey = strPrivKey;

    Sign(msg);

    if(CheckSignature(msg)){
        LogPrintf("CSporkManager::SetPrivKey - Successfully initialized as spork signer\n");
        return true;
    } else {
        return false;
    }
}

int CSporkManager::GetSporkIDByName(std::string strName)
{
    if(strName == "SPORK_2_INSTANTX") return SPORK_2_INSTANTX;
    if(strName == "SPORK_3_INSTANTX_BLOCK_FILTERING") return SPORK_3_INSTANTX_BLOCK_FILTERING;
    if(strName == "SPORK_5_MAX_VALUE") return SPORK_5_MAX_VALUE;
    if(strName == "SPORK_7_MASTERNODE_SCANNING") return SPORK_7_MASTERNODE_SCANNING;
    if(strName == "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT") return SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT;
    if(strName == "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT") return SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT;
    if(strName == "SPORK_10_MASTERNODE_PAY_UPDATED_NODES") return SPORK_10_MASTERNODE_PAY_UPDATED_NODES;
    if(strName == "SPORK_11_RESET_BUDGET") return SPORK_11_RESET_BUDGET;
    if(strName == "SPORK_12_RECONSIDER_BLOCKS") return SPORK_12_RECONSIDER_BLOCKS;
    if(strName == "SPORK_13_ENABLE_SUPERBLOCKS") return SPORK_13_ENABLE_SUPERBLOCKS;

    return -1;
}

std::string CSporkManager::GetSporkNameByID(int id)
{
    if(id == SPORK_2_INSTANTX) return "SPORK_2_INSTANTX";
    if(id == SPORK_3_INSTANTX_BLOCK_FILTERING) return "SPORK_3_INSTANTX_BLOCK_FILTERING";
    if(id == SPORK_5_MAX_VALUE) return "SPORK_5_MAX_VALUE";
    if(id == SPORK_7_MASTERNODE_SCANNING) return "SPORK_7_MASTERNODE_SCANNING";
    if(id == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) return "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT";
    if(id == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) return "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT";
    if(id == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) return "SPORK_10_MASTERNODE_PAY_UPDATED_NODES";
    if(id == SPORK_11_RESET_BUDGET) return "SPORK_11_RESET_BUDGET";
    if(id == SPORK_12_RECONSIDER_BLOCKS) return "SPORK_12_RECONSIDER_BLOCKS";
    if(id == SPORK_13_ENABLE_SUPERBLOCKS) return "SPORK_13_ENABLE_SUPERBLOCKS";

    return "Unknown";
}
<commit_msg>fix spork int error<commit_after>

#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
#include "protocol.h"
#include "spork.h"
#include "main.h"
#include "masternode-budget.h"
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;

class CSporkMessage;
class CSporkManager;

CSporkManager sporkManager;

std::map<uint256, CSporkMessage> mapSporks;
std::map<int, CSporkMessage> mapSporksActive;

void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if(fLiteMode) return; //disable all darksend/masternode related functionality

    if (strCommand == "spork")
    {
        //LogPrintf("ProcessSpork::spork\n");
        CDataStream vMsg(vRecv);
        CSporkMessage spork;
        vRecv >> spork;

        if(chainActive.Tip() == NULL) return;

        uint256 hash = spork.GetHash();
        if(mapSporksActive.count(spork.nSporkID)) {
            if(mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned){
                if(fDebug) LogPrintf("spork - seen %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
                return;
            } else {
                if(fDebug) LogPrintf("spork - got updated spork %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
            }
        }

        LogPrintf("spork - new %s ID %d Time %d bestHeight %d\n", hash.ToString(), spork.nSporkID, spork.nValue, chainActive.Tip()->nHeight);

        if(!sporkManager.CheckSignature(spork)){
            LogPrintf("spork - invalid signature\n");
            Misbehaving(pfrom->GetId(), 100);
            return;
        }

        mapSporks[hash] = spork;
        mapSporksActive[spork.nSporkID] = spork;
        sporkManager.Relay(spork);

        //does a task if needed
        ExecuteSpork(spork.nSporkID, spork.nValue);
    }
    if (strCommand == "getsporks")
    {
        std::map<int, CSporkMessage>::iterator it = mapSporksActive.begin();

        while(it != mapSporksActive.end()) {
            pfrom->PushMessage("spork", it->second);
            it++;
        }
    }

}

// grab the spork, otherwise say it's off
bool IsSporkActive(int nSporkID)
{
    int64_t r = -1;

    if(mapSporksActive.count(nSporkID)){
        r = mapSporksActive[nSporkID].nValue;
    } else {
        if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
        if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
        if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
        if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING_DEFAULT;
        if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
        if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
        if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
        if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;

        if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
    }
    if(r == -1) r = 4070908800; //return 2099-1-1 by default

    return r < GetTime();
}

// grab the value of the spork on the network, or the default
int GetSporkValue(int nSporkID)
{
    int64_t r = 0;

    if(mapSporksActive.count(nSporkID)){
        r = mapSporksActive[nSporkID].nValue;
    } else {
        if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
        if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
        if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
        if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING_DEFAULT;
        if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT;
        if(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
        if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
        if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
        if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;

        if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
    }

    return r;
}

void ExecuteSpork(int nSporkID, int nValue)
{
    if(nSporkID == SPORK_11_RESET_BUDGET && nValue == 1){
        budget.Clear();
    }

    //correct fork via spork technology
    if(nSporkID == SPORK_12_RECONSIDER_BLOCKS && nValue > 0) {
        LogPrintf("Spork::ExecuteSpork -- Reconsider Last %d Blocks\n", nValue);

        ReprocessBlocks(nValue);
    }
}

void ReprocessBlocks(int nBlocks)
{
    std::map<uint256, int64_t>::iterator it = mapRejectedBlocks.begin();
    while(it != mapRejectedBlocks.end()){
        //use a window twice as large as is usual for the nBlocks we want to reset
        if((*it).second  > GetTime() - (nBlocks*60*5)) {
            BlockMap::iterator mi = mapBlockIndex.find((*it).first);
            if (mi != mapBlockIndex.end() && (*mi).second) {
                LOCK(cs_main);

                CBlockIndex* pindex = (*mi).second;
                LogPrintf("ReprocessBlocks - %s\n", (*it).first.ToString());

                CValidationState state;
                ReconsiderBlock(state, pindex);
            }
        }
        ++it;
    }

    CValidationState state;
    {
        LOCK(cs_main);
        DisconnectBlocksAndReprocess(nBlocks);
    }

    if (state.IsValid()) {
        ActivateBestChain(state);
    }
}

bool CSporkManager::CheckSignature(CSporkMessage& spork)
{
    //note: need to investigate why this is failing
    std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);
    CPubKey pubkey(ParseHex(Params().SporkKey()));

    std::string errorMessage = "";
    if(!darkSendSigner.VerifyMessage(pubkey, spork.vchSig, strMessage, errorMessage)){
        return false;
    }

    return true;
}

bool CSporkManager::Sign(CSporkMessage& spork)
{
    std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);

    CKey key2;
    CPubKey pubkey2;
    std::string errorMessage = "";

    if(!darkSendSigner.SetKey(strMasterPrivKey, errorMessage, key2, pubkey2))
    {
        LogPrintf("CMasternodePayments::Sign - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage);
        return false;
    }

    if(!darkSendSigner.SignMessage(strMessage, errorMessage, spork.vchSig, key2)) {
        LogPrintf("CMasternodePayments::Sign - Sign message failed");
        return false;
    }

    if(!darkSendSigner.VerifyMessage(pubkey2, spork.vchSig, strMessage, errorMessage)) {
        LogPrintf("CMasternodePayments::Sign - Verify message failed");
        return false;
    }

    return true;
}

bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue)
{

    CSporkMessage msg;
    msg.nSporkID = nSporkID;
    msg.nValue = nValue;
    msg.nTimeSigned = GetTime();

    if(Sign(msg)){
        Relay(msg);
        mapSporks[msg.GetHash()] = msg;
        mapSporksActive[nSporkID] = msg;
        return true;
    }

    return false;
}

void CSporkManager::Relay(CSporkMessage& msg)
{
    CInv inv(MSG_SPORK, msg.GetHash());
    RelayInv(inv);
}

bool CSporkManager::SetPrivKey(std::string strPrivKey)
{
    CSporkMessage msg;

    // Test signing successful, proceed
    strMasterPrivKey = strPrivKey;

    Sign(msg);

    if(CheckSignature(msg)){
        LogPrintf("CSporkManager::SetPrivKey - Successfully initialized as spork signer\n");
        return true;
    } else {
        return false;
    }
}

int CSporkManager::GetSporkIDByName(std::string strName)
{
    if(strName == "SPORK_2_INSTANTX") return SPORK_2_INSTANTX;
    if(strName == "SPORK_3_INSTANTX_BLOCK_FILTERING") return SPORK_3_INSTANTX_BLOCK_FILTERING;
    if(strName == "SPORK_5_MAX_VALUE") return SPORK_5_MAX_VALUE;
    if(strName == "SPORK_7_MASTERNODE_SCANNING") return SPORK_7_MASTERNODE_SCANNING;
    if(strName == "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT") return SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT;
    if(strName == "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT") return SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT;
    if(strName == "SPORK_10_MASTERNODE_PAY_UPDATED_NODES") return SPORK_10_MASTERNODE_PAY_UPDATED_NODES;
    if(strName == "SPORK_11_RESET_BUDGET") return SPORK_11_RESET_BUDGET;
    if(strName == "SPORK_12_RECONSIDER_BLOCKS") return SPORK_12_RECONSIDER_BLOCKS;
    if(strName == "SPORK_13_ENABLE_SUPERBLOCKS") return SPORK_13_ENABLE_SUPERBLOCKS;

    return -1;
}

std::string CSporkManager::GetSporkNameByID(int id)
{
    if(id == SPORK_2_INSTANTX) return "SPORK_2_INSTANTX";
    if(id == SPORK_3_INSTANTX_BLOCK_FILTERING) return "SPORK_3_INSTANTX_BLOCK_FILTERING";
    if(id == SPORK_5_MAX_VALUE) return "SPORK_5_MAX_VALUE";
    if(id == SPORK_7_MASTERNODE_SCANNING) return "SPORK_7_MASTERNODE_SCANNING";
    if(id == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) return "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT";
    if(id == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) return "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT";
    if(id == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) return "SPORK_10_MASTERNODE_PAY_UPDATED_NODES";
    if(id == SPORK_11_RESET_BUDGET) return "SPORK_11_RESET_BUDGET";
    if(id == SPORK_12_RECONSIDER_BLOCKS) return "SPORK_12_RECONSIDER_BLOCKS";
    if(id == SPORK_13_ENABLE_SUPERBLOCKS) return "SPORK_13_ENABLE_SUPERBLOCKS";

    return "Unknown";
}
<|endoftext|>


<commit_before>// $Id$

/*
Copyright (c) 2007-2009, Trustees of The Leland Stanford Junior University
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.
Neither the name of the Stanford University 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 OWNER 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.
*/

/*stats.cpp
 *
 *class stores statistics gnerated by the trafficmanager such as the latency
 *hope count of the the flits
 *
 *reset option resets the min and max alues of this statistiscs
 */

#include "booksim.hpp"
#include <iostream>
#include <sstream>
#include <limits>
#include <cmath>
#include <cstdio>

#include "stats.hpp"

Stats::Stats( Module *parent, const string &name,
	      double bin_size, int num_bins ) :
  Module( parent, name ),
   _num_bins( num_bins ), _bin_size( bin_size ), _hist(_num_bins, 0), _num_samples(0), _sample_sum(0.0), _min(numeric_limits<double>::max()), _max(numeric_limits<double>::min())
{

}

void Stats::Clear( )
{
  _num_samples = 0;
  _sample_sum  = 0.0;

  for ( int b = 0; b < _num_bins; ++b ) {
    _hist[b] = 0;
  }
  //this could be trouble
  _min = numeric_limits<double>::max();
  _max = numeric_limits<double>::min();

  //  _reset = true;
}

double Stats::Average( ) const
{
  return _sample_sum / (double)_num_samples;
}

double Stats::Min( ) const
{
  return _min;
}

double Stats::Max( ) const
{
  return _max;
}

double Stats::Sum( ) const
{
  return _sample_sum;
}

int Stats::NumSamples( ) const
{
  return _num_samples;
}

void Stats::AddSample( double val )
{
  int b;

  _num_samples++;
  _sample_sum += val;

  _max= (val > _max )?val:_max;
  _min= (val < _min )?val:_min;

  b = (int)floor( val / _bin_size );

  //double clamp between 0 and num_bins
  b = (b < 0 )?0:((b>=_num_bins)?_num_bins - 1:b);

  _hist[b]++;
}

void Stats::AddSample( int val )
{
  AddSample( (double)val );
}

void Stats::Display( ) const
{
  cout << *this << endl;
}

ostream & operator<<(ostream & os, const Stats & s) {
  os << s._hist;
  return os;
}
<commit_msg>simplify histogram reset for stats class<commit_after>// $Id$

/*
Copyright (c) 2007-2009, Trustees of The Leland Stanford Junior University
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.
Neither the name of the Stanford University 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 OWNER 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.
*/

/*stats.cpp
 *
 *class stores statistics gnerated by the trafficmanager such as the latency
 *hope count of the the flits
 *
 *reset option resets the min and max alues of this statistiscs
 */

#include "booksim.hpp"
#include <iostream>
#include <sstream>
#include <limits>
#include <cmath>
#include <cstdio>

#include "stats.hpp"

Stats::Stats( Module *parent, const string &name,
	      double bin_size, int num_bins ) :
  Module( parent, name ),
   _num_bins( num_bins ), _bin_size( bin_size ), _hist(_num_bins, 0), _num_samples(0), _sample_sum(0.0), _min(numeric_limits<double>::max()), _max(numeric_limits<double>::min())
{

}

void Stats::Clear( )
{
  _num_samples = 0;
  _sample_sum  = 0.0;

  _hist.assign(_num_bins, 0);

  _min = numeric_limits<double>::max();
  _max = numeric_limits<double>::min();

  //  _reset = true;
}

double Stats::Average( ) const
{
  return _sample_sum / (double)_num_samples;
}

double Stats::Min( ) const
{
  return _min;
}

double Stats::Max( ) const
{
  return _max;
}

double Stats::Sum( ) const
{
  return _sample_sum;
}

int Stats::NumSamples( ) const
{
  return _num_samples;
}

void Stats::AddSample( double val )
{
  int b;

  _num_samples++;
  _sample_sum += val;

  _max= (val > _max )?val:_max;
  _min= (val < _min )?val:_min;

  b = (int)floor( val / _bin_size );

  //double clamp between 0 and num_bins
  b = (b < 0 )?0:((b>=_num_bins)?_num_bins - 1:b);

  _hist[b]++;
}

void Stats::AddSample( int val )
{
  AddSample( (double)val );
}

void Stats::Display( ) const
{
  cout << *this << endl;
}

ostream & operator<<(ostream & os, const Stats & s) {
  os << s._hist;
  return os;
}
<|endoftext|>


<commit_before>/* (C) by B. Mehnert (nickname bhmehnert) under the license presented in this directory.
 *
 * This program computes a vector of the primes smaller or equal to a given integer n.
 * The algorithm used is the 'Sieve of Eratosthenes', which is a quite fast algorithm.
 * Our choice of data structure is a doubly linked list. */

#include <iostream>
#include <cmath>  // I need this for computing the square root of a number.
#include <vector>

using namespace std;

typedef struct DLLNode
{
	DLLNode *lNode;
	DLLNode *rNode;
	int Data;
}DLLNode;

/* Function 'primes':
 * Input: An integer n => 2.
 * Output: A vector containing all primes p <=n */

vector<int>  primes(int n)
{
	// First we initialize the list where we cross out the non-primes.

	DLLNode *List = new DLLNode [n-1];

	// Store the n-1 numbers 2,3,4,5,...,n in the doubly linked list List[0] <-> List[1] <-> .. <-> List[n-2].

	for (int i=0; i < n-1; i++)
	{
		if (i > 0) List[i].lNode = &List[i-1];
	    if (i < n-2) List[i].rNode = &List[i+1];
	    List[i].Data = i+2;
	};

	int t = (int) sqrt((float) n);  // Any non-prime <= n has a prime divisor <= t = [sqrt(n)].

	DLLNode *first = &List[0];
	DLLNode *pos = &List[0];
	DLLNode *run = &List[0];

	// Now follows the main algorithm. Note that the integer d is always a prime, beginning with d=2.

	int d = pos -> Data;

	while (d <= t)
	{
		// Go through all numbers to the right of pos which are not crossed out yet
		// and cross those out which are multiples of d.

		while (run -> rNode != NULL)
		{
			run = run -> rNode;
			if ((run -> Data) % d == 0)
			{
				if (run -> rNode != NULL)
				{
					(run -> lNode) -> rNode = run -> rNode;
					(run -> rNode) -> lNode = run -> lNode;
				}
				else
				{
					(run -> lNode) -> rNode = NULL;
				};
			};
		};
		pos = pos -> rNode;
		run = pos;
		d = pos -> Data;
	};

	run = first;
	int counter = 0;
	vector<int> output;

	while (run != NULL)
	{
		output.push_back(run -> Data);
		run = run -> rNode;
	};

	// Free the memory of the list we used:
	delete [] List;

	return output;
}

int main()
{
	// Let's compute a list of the prime numbers p with 2 <= p <= 1000000
	// and print them out.

	vector<int> v = primes(1000000);

    for (int i=0; i < v.size(); i++)
	{
		cout << v[i] << ", ";
	};

	return 0;
}
<commit_msg>Implementation of the sieve of Eratosthenes ...<commit_after>/* (C) by B. Mehnert (nickname bhmehnert) under the license presented in this directory.
 *
 * This program computes a vector of the primes smaller or equal to a given integer n.
 * The algorithm used is the 'Sieve of Eratosthenes', which is a quite fast algorithm.
 * Our choice of data structure is a doubly linked list. */

#include <iostream>
#include <cmath>  // I need this for computing the square root of a number.
#include <vector>

using namespace std;

typedef struct DLLNode
{
	DLLNode *lNode;
	DLLNode *rNode;
	int Data;
}DLLNode;

/* Function 'primes':
 * Input: An integer n => 2.
 * Output: A vector containing all primes p <=n */

vector<int>  primes(int n)
{
	// First we initialize the list where we cross out the non-primes.

	DLLNode *List = new DLLNode [n-1];

	// Store the n-1 numbers 2,3,4,5,...,n in the doubly linked list List[0] <-> List[1] <-> .. <-> List[n-2].

	for (int i=0; i < n-1; i++)
	{
		if (i > 0) List[i].lNode = &List[i-1];
	    if (i < n-2) List[i].rNode = &List[i+1];
	    List[i].Data = i+2;
	};

	int t = (int) sqrt((float) n);  // Any non-prime <= n has a prime divisor <= t = [sqrt(n)].

	DLLNode *first = &List[0];
	DLLNode *pos = &List[0];
	DLLNode *run = &List[0];

	// Now follows the main algorithm. Note that the integer d is always a prime, beginning with d=2.

	int d = pos -> Data;

	while (d <= t)
	{
		// Go through all numbers to the right of pos which are not crossed out yet
		// and cross those out which are multiples of d.

		while (run -> rNode != NULL)
		{
			run = run -> rNode;
			if ((run -> Data) % d == 0)
			{
				if (run -> rNode != NULL)
				{
					(run -> lNode) -> rNode = run -> rNode;
					(run -> rNode) -> lNode = run -> lNode;
				}
				else
				{
					(run -> lNode) -> rNode = NULL;
				};
			};
		};
		pos = pos -> rNode;
		run = pos;
		d = pos -> Data;
	};

	run = first;
	vector<int> output;

	while (run != NULL)
	{
		output.push_back(run -> Data);
		run = run -> rNode;
	};

	// Free the memory of the list we used:
	delete [] List;

	return output;
}

int main()
{
	// Let's compute a list of the prime numbers p with 2 <= p <= 1000000
	// and print them out.

	vector<int> v = primes(1000000);

    for (int i=0; i < v.size(); i++)
	{
		cout << v[i] << ", ";
	};

	return 0;
}
<|endoftext|>


<commit_before>#include <cstring>

#include <iostream>
#include <thread>
#include <iomanip>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <linux/ip.h>
#include <netinet/udp.h>

#include "colors.h"
#include "interface.h"
#include "print.h"

using namespace std;
using namespace Colors;

void sigint_handler(int);
void sniff(const int, const ifreq&);

bool stop = false;
static pthread_mutex_t cs_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    std::cerr << "Usage: phantom <interface>" << endl;
    exit(-1);
  }

  if (initSignal(sigint_handler) < 0)
    exit(-1);

  int socket;
  if (initSocket(socket) < 0)
    exit(-1);

  struct ifreq ifr;
  strcpy(ifr.ifr_name, argv[1]);

  if (initInterface(socket, ifr) < 0)
    exit(-1);

  std::thread sniffer(sniff, socket, ifr);
  sniffer.join();

  if (resetInterface(socket, ifr) < 0)
    exit(-1);

  if (closeSocket(socket) < 0)
    exit(-1);

  return 0;
}

void sigint_handler(int)
{
  cout << yellow << "Received SIGINT to interrupt execution." << reset << endl;
  pthread_mutex_lock(&cs_mutex);
  stop = true;
  pthread_mutex_unlock(&cs_mutex);
}

void sniff(const int socket, const ifreq& ifr)
{
  cout << ifreq_to_str(ifr);

  u_char buff[ETHER_MAX_LEN];

  for (;;)
  {
    pthread_mutex_lock(&cs_mutex);
    if (stop)
    {
      pthread_mutex_unlock(&cs_mutex);
      break;
    }
    pthread_mutex_unlock(&cs_mutex);

    if (recv(socket, (char*)&buff, sizeof(buff), 0x00) < ETHER_MIN_LEN)
      continue;

    struct ether_header ether;
    memcpy(&ether, &buff, sizeof(ether));

    if (ntohs(ether.ether_type) == ETHERTYPE_IP)
    {
      cout << ether_to_str(ether);

      struct iphdr ip;
      memcpy(&ip, &buff[ETHER_HDR_LEN], 1);
      memcpy(&ip, &buff[ETHER_HDR_LEN], ip.ihl * 4);
      cout << ip_to_str(ip);

      if (ntohs(ip.protocol) == IPPROTO_UDP)
      {
        cout << endl << red << "Received UDP packet!" << reset << endl;
      }
    }
  }
}
<commit_msg>Only print UDP packets.<commit_after>#include <cstring>

#include <iostream>
#include <thread>
#include <iomanip>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <linux/ip.h>
#include <netinet/udp.h>

#include "colors.h"
#include "interface.h"
#include "print.h"

using namespace std;
using namespace Colors;

void sigint_handler(int);
void sniff(const int, const ifreq&);

bool stop = false;
static pthread_mutex_t cs_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    std::cerr << "Usage: phantom <interface>" << endl;
    exit(-1);
  }

  if (initSignal(sigint_handler) < 0)
    exit(-1);

  int socket;
  if (initSocket(socket) < 0)
    exit(-1);

  struct ifreq ifr;
  strcpy(ifr.ifr_name, argv[1]);

  if (initInterface(socket, ifr) < 0)
    exit(-1);

  std::thread sniffer(sniff, socket, ifr);
  sniffer.join();

  if (resetInterface(socket, ifr) < 0)
    exit(-1);

  if (closeSocket(socket) < 0)
    exit(-1);

  return 0;
}

void sigint_handler(int)
{
  cout << yellow << "Received SIGINT to interrupt execution." << reset << endl;
  pthread_mutex_lock(&cs_mutex);
  stop = true;
  pthread_mutex_unlock(&cs_mutex);
}

void sniff(const int socket, const ifreq& ifr)
{
  cout << ifreq_to_str(ifr);

  u_char buff[ETHER_MAX_LEN];

  for (;;)
  {
    pthread_mutex_lock(&cs_mutex);
    if (stop)
    {
      pthread_mutex_unlock(&cs_mutex);
      break;
    }
    pthread_mutex_unlock(&cs_mutex);

    if (recv(socket, (char*)&buff, sizeof(buff), 0x00) < ETHER_MIN_LEN)
      continue;

    struct ether_header ether;
    memcpy(&ether, &buff, sizeof(ether));

    if (ntohs(ether.ether_type) == ETHERTYPE_IP)
    {

      struct iphdr ip;
      memcpy(&ip, &buff[ETHER_HDR_LEN], 1);
      memcpy(&ip, &buff[ETHER_HDR_LEN], ip.ihl * 4);

      if (ntohs(ip.protocol) == IPPROTO_UDP)
      {
        cout << ether_to_str(ether);
        cout << ip_to_str(ip);
        cout << endl << red << "Received UDP packet!" << reset << endl;
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017, Yeolar
 */

#include <map>
#include <set>
#include <string>
#include <typeinfo>
#include "rddoc/framework/Config.h"
#include "rddoc/io/FileUtil.h"
#include "rddoc/net/Actor.h"
#include "rddoc/parallel/JobHandler.h"
#include "rddoc/plugins/monitor/Monitor.h"
#include "rddoc/util/DAG.h"
#include "rddoc/util/Logging.h"

namespace rdd {

void configLogging(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config logging error: " << j;
    return;
  }
  RDDLOG(INFO) << "config logger";
  logging::BaseLogger::Options opts;
  opts.logfile = json::get(j, "logfile", "rdd.log");
  opts.level   = json::get(j, "level", 1);
  opts.rotate  = json::get(j, "rotate", 0);
  Singleton<logging::RDDLogger>::get()->setOptions(opts);
}

void configActor(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config actor error: " << j;
    return;
  }
  RDDLOG(INFO) << "config actor";
  Actor::Options opts;
  opts.stack_size   = json::get(j, "stack_size", 64*1024);
  opts.conn_limit   = json::get(j, "conn_limit", 100000);
  opts.task_limit   = json::get(j, "task_limit", 4000);
  opts.poll_size    = json::get(j, "poll_size", 1024);
  opts.poll_timeout = json::get(j, "poll_timeout", 1000);
  opts.forwarding   = json::get(j, "forwarding", false);
  Singleton<Actor>::get()->setOptions(opts);
}

void configTaskThreadPool(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config thread error: " << j;
    return;
  }
  for (auto& kv : j.items()) {
    const dynamic& k = kv.first;
    const dynamic& v = kv.second;
    RDDLOG(INFO) << "config thread." << k;
    TaskThreadPool::Options thread_opt;
    thread_opt.thread_count       = json::get(v, "thread_count", 4);
    thread_opt.thread_count_limit = json::get(v, "thread_count_limit", 0);
    thread_opt.bindcpu            = json::get(v, "bindcpu", false);
    thread_opt.waiting_task_limit = json::get(v, "waiting_task_limit", 100);
    if (k == "0") {
      Singleton<Actor>::get()->addPool(0, thread_opt);
    } else {
      auto service = json::get(v, "service", "");
      int port = k.asInt();
      if (service == "") {
        RDDLOG(FATAL) << "config thread." << k << " error: " << v;
        return;
      }
      TimeoutOption timeout_opt;
      timeout_opt.ctimeout = json::get(v, "conn_timeout", 100000);
      timeout_opt.rtimeout = json::get(v, "recv_timeout", 300000);
      timeout_opt.wtimeout = json::get(v, "send_timeout", 1000000);
      Singleton<Actor>::get()->configService(
          service, port, timeout_opt, thread_opt);
    }
  }
}

void configNetCopy(const dynamic& j) {
  if (!j.isArray()) {
    RDDLOG(FATAL) << "config net.copy error: " << j;
    return;
  }
  RDDLOG(INFO) << "config net.copy";
  for (auto& i : j) {
    Actor::ForwardTarget t;
    t.port  = json::get(i, "port", 0);
    t.fpeer = {json::get(i, "fhost", ""), json::get(i, "fport", 0)};
    t.flow  = json::get(i, "flow", 100);
    Singleton<Actor>::get()->addForwardTarget(t);
  }
}

void configMonitor(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config monitor error: " << j;
    return;
  }
  RDDLOG(INFO) << "config monitor";
  if (json::get(j, "open", false)) {
    Singleton<Monitor>::get()->setPrefix(json::get(j, "prefix", "rdd"));
    Singleton<Monitor>::get()->start();
  }
}

void configJobGraph(const dynamic& j) {
  if (!j.isArray()) {
    RDDLOG(FATAL) << "config job.graph error: " << j;
    return;
  }
  RDDLOG(INFO) << "config job.graph";
  for (auto& i : j) {
    auto name = json::get(i, "name", "");
    int id = json::get(i, "id", 0);
    auto next = json::getArray<int>(i, "next");
    Singleton<JobHandlerManager>::get()->addJobHandler(id, name);
    Singleton<DAG<int>>::get()->addNode(id, next);
  }
}

void config(const char* name, std::initializer_list<ConfigTask> confs) {
  RDDLOG(INFO) << "config rdd by conf: " << name;

  std::string s;
  readFile(name, s);
  dynamic j = parseJson(json::stripComments(s));
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config error";
    return;
  }
  RDDLOG(DEBUG) << j;

  for (auto& conf : confs) {
    conf.first(json::resolve(j, conf.second));
  }
}

}

<commit_msg>check file read error<commit_after>/*
 * Copyright (C) 2017, Yeolar
 */

#include <map>
#include <set>
#include <string>
#include <typeinfo>
#include "rddoc/framework/Config.h"
#include "rddoc/io/FileUtil.h"
#include "rddoc/net/Actor.h"
#include "rddoc/parallel/JobHandler.h"
#include "rddoc/plugins/monitor/Monitor.h"
#include "rddoc/util/DAG.h"
#include "rddoc/util/Logging.h"

namespace rdd {

void configLogging(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config logging error: " << j;
    return;
  }
  RDDLOG(INFO) << "config logger";
  logging::BaseLogger::Options opts;
  opts.logfile = json::get(j, "logfile", "rdd.log");
  opts.level   = json::get(j, "level", 1);
  opts.rotate  = json::get(j, "rotate", 0);
  Singleton<logging::RDDLogger>::get()->setOptions(opts);
}

void configActor(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config actor error: " << j;
    return;
  }
  RDDLOG(INFO) << "config actor";
  Actor::Options opts;
  opts.stack_size   = json::get(j, "stack_size", 64*1024);
  opts.conn_limit   = json::get(j, "conn_limit", 100000);
  opts.task_limit   = json::get(j, "task_limit", 4000);
  opts.poll_size    = json::get(j, "poll_size", 1024);
  opts.poll_timeout = json::get(j, "poll_timeout", 1000);
  opts.forwarding   = json::get(j, "forwarding", false);
  Singleton<Actor>::get()->setOptions(opts);
}

void configTaskThreadPool(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config thread error: " << j;
    return;
  }
  for (auto& kv : j.items()) {
    const dynamic& k = kv.first;
    const dynamic& v = kv.second;
    RDDLOG(INFO) << "config thread." << k;
    TaskThreadPool::Options thread_opt;
    thread_opt.thread_count       = json::get(v, "thread_count", 4);
    thread_opt.thread_count_limit = json::get(v, "thread_count_limit", 0);
    thread_opt.bindcpu            = json::get(v, "bindcpu", false);
    thread_opt.waiting_task_limit = json::get(v, "waiting_task_limit", 100);
    if (k == "0") {
      Singleton<Actor>::get()->addPool(0, thread_opt);
    } else {
      auto service = json::get(v, "service", "");
      int port = k.asInt();
      if (service == "") {
        RDDLOG(FATAL) << "config thread." << k << " error: " << v;
        return;
      }
      TimeoutOption timeout_opt;
      timeout_opt.ctimeout = json::get(v, "conn_timeout", 100000);
      timeout_opt.rtimeout = json::get(v, "recv_timeout", 300000);
      timeout_opt.wtimeout = json::get(v, "send_timeout", 1000000);
      Singleton<Actor>::get()->configService(
          service, port, timeout_opt, thread_opt);
    }
  }
}

void configNetCopy(const dynamic& j) {
  if (!j.isArray()) {
    RDDLOG(FATAL) << "config net.copy error: " << j;
    return;
  }
  RDDLOG(INFO) << "config net.copy";
  for (auto& i : j) {
    Actor::ForwardTarget t;
    t.port  = json::get(i, "port", 0);
    t.fpeer = {json::get(i, "fhost", ""), json::get(i, "fport", 0)};
    t.flow  = json::get(i, "flow", 100);
    Singleton<Actor>::get()->addForwardTarget(t);
  }
}

void configMonitor(const dynamic& j) {
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config monitor error: " << j;
    return;
  }
  RDDLOG(INFO) << "config monitor";
  if (json::get(j, "open", false)) {
    Singleton<Monitor>::get()->setPrefix(json::get(j, "prefix", "rdd"));
    Singleton<Monitor>::get()->start();
  }
}

void configJobGraph(const dynamic& j) {
  if (!j.isArray()) {
    RDDLOG(FATAL) << "config job.graph error: " << j;
    return;
  }
  RDDLOG(INFO) << "config job.graph";
  for (auto& i : j) {
    auto name = json::get(i, "name", "");
    int id = json::get(i, "id", 0);
    auto next = json::getArray<int>(i, "next");
    Singleton<JobHandlerManager>::get()->addJobHandler(id, name);
    Singleton<DAG<int>>::get()->addNode(id, next);
  }
}

void config(const char* name, std::initializer_list<ConfigTask> confs) {
  RDDLOG(INFO) << "config rdd by conf: " << name;

  std::string s;
  if (!readFile(name, s)) {
    RDDLOG(FATAL) << "config error: file read error: " << name;
    return;
  }
  dynamic j = parseJson(json::stripComments(s));
  if (!j.isObject()) {
    RDDLOG(FATAL) << "config error: JSON parse error";
    return;
  }
  RDDLOG(DEBUG) << j;

  for (auto& conf : confs) {
    conf.first(json::resolve(j, conf.second));
  }
}

}

<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "ax2550/StampedEncoders.h"
#include <string>
#include <cmath>
#include "ax2550/ax2550.h"

using namespace ax2550;
using std::string;

AX2550 *mc;
ros::Publisher encoder_pub;

static double ENCODER_RESOLUTION = 1250*4*20;
double wheel_circumference = 0.785;
double wheel_base_length = 0.47;
double wheel_diameter = 0.25;
double encoder_poll_rate;
std::string odom_frame_id;
size_t error_count;
double target_speed_right = 0.0;
double target_speed_left = 0.0;

double rot_cov = 0.0;
double pos_cov = 0.0;

const int timeout_sec = 2.0;
ros::Time time_last;

// Persistent variables
double prev_x = 0, prev_y = 0, prev_w = 0;
ros::Time prev_time;

void cmd_velCallback(const geometry_msgs::Twist::ConstPtr& msg)
{
  time_last = ros::Time::now();
  if(mc == NULL || !mc->isConnected())
    return;

  //set the targets
  target_speed_right = msg->linear.x;
  target_speed_left = msg->linear.y;
}

void controlLoop()
{
  // ROS_INFO("Relative move commands: %f %f", target_speed, target_direction);
  try
  {
	  //SAFETY TIME OUT
	  //if a command is not received for 2 seconds the motors time out
	  double time_past = (ros::Time::now() - time_last).toSec();
	  if(time_past > timeout_sec)
	  {
		  mc->move(0,0);
		  ROS_WARN("No velocity commands received - motors timed out");
	  }
	  else
	  {
		  mc->move(target_speed_right, target_speed_left);
	  }
  }
  catch(const std::exception &e)
  {
	  if (string(e.what()).find("did not receive") != string::npos || string(e.what()).find("failed to receive an echo") != string::npos)
	  {
      ROS_WARN("Error commanding the motors: %s", e.what());
  	}
	  else
	  {
      ROS_ERROR("Error commanding the motors: %s", e.what());
      mc->disconnect();
  	}
  }
}

void errorMsgCallback(const std::string &msg)
{
  ROS_ERROR("%s", msg.c_str());
}

void warnMsgCallback(const std::string &msg)
{
  ROS_WARN("%s", msg.c_str());
}

void infoMsgCallback(const std::string &msg)
{
  ROS_INFO("%s", msg.c_str());
}

void debugMsgCallback(const std::string &msg)
{
  ROS_DEBUG("%s", msg.c_str());
}

void queryEncoders()
{
  // Make sure we are connected
  if(!ros::ok() || mc == NULL || !mc->isConnected())
    return;

  long encoder1, encoder2;
  ros::Time now = ros::Time::now();
  // Retreive the data
  try
  {
    mc->queryEncoders(encoder1, encoder2, true);
    if (error_count > 0)
	  {
      error_count -= 1;
    }
  }
  catch(std::exception &e)
  {
    if (string(e.what()).find("failed to receive ") != string::npos && error_count != 10)
	  {
      error_count += 1;
      ROS_WARN("Error reading the Encoders: %s", e.what());
    }
	  else
	  {
      ROS_ERROR("Error reading the Encoders: %s", e.what());
      mc->disconnect();
    }
    return;
  }

  double delta_time = (now - prev_time).toSec();
  prev_time = now;

  ax2550::StampedEncoders encoder_msg;

  encoder_msg.header.stamp = now;
  encoder_msg.header.frame_id = "front_encoders";
  encoder_msg.encoders.time_delta = delta_time;
  encoder_msg.encoders.left_wheel = encoder2;
  encoder_msg.encoders.right_wheel = -encoder1;

  encoder_pub.publish(encoder_msg);
}

int main(int argc, char **argv)
{
  // Node setup
  ros::init(argc, argv, "ax2550_node_front");
  ros::NodeHandle n;
  prev_time = ros::Time::now();

  // Serial port parameter
  std::string port;
  n.param("serial_port", port, std::string("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A501IKWU-if00-port0"));

  // Wheel diameter parameter
  n.param("wheel_diameter", wheel_diameter, 0.3048);

  wheel_circumference = wheel_diameter * M_PI;

  // Wheel base length
  n.param("wheel_base_length", wheel_base_length, 0.9144);

  // Odom Frame id parameter
  n.param("odom_frame_id", odom_frame_id, std::string("front_odom"));

  // Load up some covariances from parameters
  n.param("rotation_covariance",rot_cov, 1.0);
  n.param("position_covariance",pos_cov, 1.0);

  // Setup Encoder polling
  n.param("encoder_poll_rate", encoder_poll_rate, 25.0); //default 25.0
  ros::Rate encoder_rate(encoder_poll_rate);

  // Encoder Publisher
  encoder_pub = n.advertise<ax2550::StampedEncoders>("/omnimaxbot/front/encoders", 5);

  // cmd_vel Subscriber
  ros::Subscriber sub = n.subscribe("/omnimaxbot/front/cmd_vel", 1, cmd_velCallback);

  // Spinner
  ros::AsyncSpinner spinner(1);
  spinner.start();

  while(ros::ok())
  {
    ROS_INFO("AX2550 connecting to port %s", port.c_str());
    try
	  {
      mc = new AX2550();
      mc->warn = warnMsgCallback;
      mc->info = infoMsgCallback;
      mc->debug = debugMsgCallback;
      mc->connect(port);
    }
	  catch(std::exception &e)
	  {
      ROS_ERROR("Failed to connect to the AX2550: %s", e.what());
      if (mc != NULL)
	    {
      	mc->disconnect();
      }
    }
    int count = 0;
    while(mc != NULL && mc->isConnected() && ros::ok())
	  {
      queryEncoders();
      if (count == 1)
      {
        controlLoop();
        count = 0;
      }
      else
      {
        count += 1;
      }
      encoder_rate.sleep();
    }
    if (mc != NULL)
    {
    	delete mc;
    }
    mc = NULL;
    if(!ros::ok())
      break;
    ROS_INFO("Will try to reconnect to the AX2550 in 5 seconds.");
    for (int i = 0; i < 100; ++i)
    {
    	ros::Duration(5.0/100.0).sleep();
    	if (!ros::ok())
    	  break;
    }
    target_speed_right = 0.0;
    target_speed_left = 0.0;
  }

  spinner.stop();

  return 0;
}
<commit_msg>Updated spacing<commit_after>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "ax2550/StampedEncoders.h"
#include <string>
#include <cmath>
#include "ax2550/ax2550.h"

using namespace ax2550;
using std::string;

AX2550 *mc;
ros::Publisher encoder_pub;

static double ENCODER_RESOLUTION = 1250*4*20;
double wheel_circumference = 0.785;
double wheel_base_length = 0.47;
double wheel_diameter = 0.25;
double encoder_poll_rate;
std::string odom_frame_id;
size_t error_count;
double target_speed_right = 0.0;
double target_speed_left = 0.0;

double rot_cov = 0.0;
double pos_cov = 0.0;

const int timeout_sec = 2.0;
ros::Time time_last;

// Persistent variables
double prev_x = 0, prev_y = 0, prev_w = 0;
ros::Time prev_time;

void cmd_velCallback(const geometry_msgs::Twist::ConstPtr& msg)
{
  time_last = ros::Time::now();
  if(mc == NULL || !mc->isConnected())
    return;

  //set the targets
  target_speed_right = msg->linear.x;
  target_speed_left = msg->linear.y;
}

void controlLoop()
{
  // ROS_INFO("Relative move commands: %f %f", target_speed, target_direction);
  try
  {
    //SAFETY TIME OUT
    //if a command is not received for 2 seconds the motors time out
    double time_past = (ros::Time::now() - time_last).toSec();
    if(time_past > timeout_sec)
    {
      mc->move(0,0);
      ROS_WARN("No velocity commands received - motors timed out");
    }
    else
    {
      mc->move(target_speed_right, target_speed_left);
    }
  }
  catch(const std::exception &e)
  {
    if (string(e.what()).find("did not receive") != string::npos || string(e.what()).find("failed to receive an echo") != string::npos)
    {
      ROS_WARN("Error commanding the motors: %s", e.what());
    }
    else
    {
      ROS_ERROR("Error commanding the motors: %s", e.what());
      mc->disconnect();
    }
  }
}

void errorMsgCallback(const std::string &msg)
{
  ROS_ERROR("%s", msg.c_str());
}

void warnMsgCallback(const std::string &msg)
{
  ROS_WARN("%s", msg.c_str());
}

void infoMsgCallback(const std::string &msg)
{
  ROS_INFO("%s", msg.c_str());
}

void debugMsgCallback(const std::string &msg)
{
  ROS_DEBUG("%s", msg.c_str());
}

void queryEncoders()
{
  // Make sure we are connected
  if(!ros::ok() || mc == NULL || !mc->isConnected())
    return;

  long encoder1, encoder2;
  ros::Time now = ros::Time::now();
  // Retreive the data
  try
  {
    mc->queryEncoders(encoder1, encoder2, true);
    if (error_count > 0)
    {
      error_count -= 1;
    }
  }
  catch(std::exception &e)
  {
    if (string(e.what()).find("failed to receive ") != string::npos && error_count != 10)
    {
      error_count += 1;
      ROS_WARN("Error reading the Encoders: %s", e.what());
    }
    else
    {
      ROS_ERROR("Error reading the Encoders: %s", e.what());
      mc->disconnect();
    }
    return;
  }

  double delta_time = (now - prev_time).toSec();
  prev_time = now;

  ax2550::StampedEncoders encoder_msg;

  encoder_msg.header.stamp = now;
  encoder_msg.header.frame_id = "front_encoders";
  encoder_msg.encoders.time_delta = delta_time;
  encoder_msg.encoders.left_wheel = encoder2;
  encoder_msg.encoders.right_wheel = -encoder1;

  encoder_pub.publish(encoder_msg);
}

int main(int argc, char **argv)
{
  // Node setup
  ros::init(argc, argv, "ax2550_node_front");
  ros::NodeHandle n;
  prev_time = ros::Time::now();

  // Serial port parameter
  std::string port;
  n.param("serial_port", port, std::string("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A501IKWU-if00-port0"));

  // Wheel diameter parameter
  n.param("wheel_diameter", wheel_diameter, 0.3048);

  wheel_circumference = wheel_diameter * M_PI;

  // Wheel base length
  n.param("wheel_base_length", wheel_base_length, 0.9144);

  // Odom Frame id parameter
  n.param("odom_frame_id", odom_frame_id, std::string("front_odom"));

  // Load up some covariances from parameters
  n.param("rotation_covariance",rot_cov, 1.0);
  n.param("position_covariance",pos_cov, 1.0);

  // Setup Encoder polling
  n.param("encoder_poll_rate", encoder_poll_rate, 25.0); //default 25.0
  ros::Rate encoder_rate(encoder_poll_rate);

  // Encoder Publisher
  encoder_pub = n.advertise<ax2550::StampedEncoders>("/omnimaxbot/front/encoders", 5);

  // cmd_vel Subscriber
  ros::Subscriber sub = n.subscribe("/omnimaxbot/front/cmd_vel", 1, cmd_velCallback);

  // Spinner
  ros::AsyncSpinner spinner(1);
  spinner.start();

  while(ros::ok())
  {
    ROS_INFO("AX2550 connecting to port %s", port.c_str());
    try
    {
      mc = new AX2550();
      mc->warn = warnMsgCallback;
      mc->info = infoMsgCallback;
      mc->debug = debugMsgCallback;
      mc->connect(port);
    }
    catch(std::exception &e)
    {
      ROS_ERROR("Failed to connect to the AX2550: %s", e.what());
      if (mc != NULL)
      {
      	mc->disconnect();
      }
    }
    int count = 0;
    while(mc != NULL && mc->isConnected() && ros::ok())
    {
      queryEncoders();
      if (count == 1)
      {
        controlLoop();
        count = 0;
      }
      else
      {
        count += 1;
      }
      encoder_rate.sleep();
    }
    if (mc != NULL)
    {
    	delete mc;
    }
    mc = NULL;
    if(!ros::ok())
      break;
    ROS_INFO("Will try to reconnect to the AX2550 in 5 seconds.");
    for (int i = 0; i < 100; ++i)
    {
      ros::Duration(5.0/100.0).sleep();
      if (!ros::ok())
        break;
    }
    target_speed_right = 0.0;
    target_speed_left = 0.0;
  }

  spinner.stop();

  return 0;
}
<|endoftext|>


<commit_before>#include <vector>
#include <string>
#include <sstream>

using namespace std;

#include "Coordinate.h"
#include "potions.h"
#include "scrolls.h"
#include "io.h"
#include "armor.h"
#include "pack.h"
#include "rings.h"
#include "misc.h"
#include "level.h"
#include "player.h"
#include "weapons.h"
#include "wand.h"
#include "os.h"
#include "options.h"
#include "rogue.h"

#include "things.h"

/* Only oi_prob is used */
vector<obj_info> things = {
/*   oi_name oi_prob oi_worth oi_guess oi_know */
    { "potion",	26,	0,	"",	false },
    { "scroll",	36,	0,	"",	false },
    { "food",	16,	0,	"",	false },
    { "weapon",	 7,	0,	"",	false },
    { "armor",	 7,	0,	"",	false },
    { "ring",	 4,	0,	"",	false },
    { "stick",	 4,	0,	"",	false },
};

string
inv_name(Item const* item, bool drop)
{
  stringstream buffer;

  switch (item->o_type)
  {
    case POTION: {
      char buf[MAXSTR];
      potion_description(item, buf);
      buffer << buf;
    } break;
    case RING: {
      char buf[MAXSTR];
      ring_description(item, buf);
      buffer << buf;
    } break;
    case STICK: {
      char buf[MAXSTR];
      wand_description(item, buf);
      buffer << buf;
    } break;
    case SCROLL: {
      char buf[MAXSTR];
      scroll_description(item, buf);
      buffer << buf;
    } break;
    case WEAPON: case AMMO: {
      char buf[MAXSTR];
      weapon_description(item, buf);
      buffer << buf;
    } break;
    case ARMOR: buffer << armor_description(item); break;
    case FOOD: {
      string obj_type = item->o_which == 1 ? "fruit" : "food ration";
      if (item->o_count == 1) {
        buffer << "A " << obj_type;
      } else {
        buffer << item->o_count << " " << obj_type;
      }
    } break;
    case AMULET: {
      buffer << "The Amulet of Yendor";
    } break;
    case GOLD: {
      buffer << item->o_goldval << " Gold pieces";
    } break;
    default:
      io_msg("You feel a disturbance in the force");
      buffer << "Something bizarre " << unctrl(static_cast<chtype>(item->o_type));
      break;
  }

  string return_value = buffer.str();
  return_value.at(0) = static_cast<char>(drop
      ? tolower(return_value.at(0))
      : toupper(return_value.at(0)));
  return return_value;
}

Item*
new_food(int which)
{
  /* Reset levels-without-food counter */
  levels_without_food = 0;

  Item* cur = new Item();
  cur->o_count = 1;
  cur->o_type = FOOD;
  switch (which)
  {
    case 0: case 1: cur->o_which = which; break;
    default: cur->o_which = os_rand_range(10) ? 0 : 1; break;
  }
  return cur;
}

Item*
new_amulet(void)
{
  Item* obj       = new Item();
  obj->o_damage  = {1, 2};
  obj->o_hurldmg = {1, 2};
  obj->o_type    = AMULET;

  return obj;
}

Item*
new_thing(void)
{
  /* Decide what kind of object it will be
   * If we haven't had food for a while, let it be food. */
  int r;
  if (levels_without_food > 3)
    r = 2;
  else
    r = static_cast<int>(pick_one(things, things.size()));

  Item* cur = nullptr;
  switch (r)
  {
    case 0: cur = potion_create(-1); break;
    case 1: cur = scroll_create(-1); break;
    case 2: cur = new_food(-1); break;
    case 3: cur = weapon_create(-1, true); break;
    case 4: cur = armor_create(-1, true); break;
    case 5: cur = ring_create(-1, true); break;
    case 6: cur = wand_create(-1); break;
    default:
      io_msg("Picked a bad kind of object (this should not happen)");
      io_wait_for_key(KEY_SPACE);
      break;
  }

  if (cur == nullptr) {
    throw runtime_error("curr is null");
  }
  if (cur->o_damage.sides < 0 || cur->o_damage.dices < 0) {
    throw runtime_error("cur->damage is negative");
  }
  if (cur->o_hurldmg.sides < 0 || cur->o_hurldmg.dices < 0) {
    throw runtime_error("cur->hurldmg is negative");
  }
  return cur;
}

size_t
pick_one(vector<obj_info>& start, size_t nitems)
{
  for (size_t rand = static_cast<size_t>(os_rand_range(100)), i = 0; i < nitems; ++i)
    if (rand < start.at(i).oi_prob)
      return i;
    else
      rand -= start.at(i).oi_prob;

  /* The functions should have returned by now */
  throw range_error("Probability was not in range");
}

/* list what the player has discovered of this type */
static void
discovered_by_type(char type, vector<obj_info>& info, size_t max_items)
{
  WINDOW *printscr = dupwin(stdscr);

  Coordinate orig_pos;
  getyx(stdscr, orig_pos.y, orig_pos.x);

  Item printable_object;
  memset(&printable_object, 0, sizeof(printable_object));
  printable_object.o_type = type;
  printable_object.o_flags = 0;
  printable_object.o_count = 1;

  int items_found = 0;
  for (size_t i = 0; i < max_items; ++i)
    if (info.at(i).oi_know || !info.at(i).oi_guess.empty())
    {
      printable_object.o_which = static_cast<int>(i);
      mvwprintw(printscr, ++items_found, 1,
                "%s", inv_name(&printable_object, false).c_str());
    }

  if (items_found == 0)
  {
    string type_as_str = nullptr;
    switch (type)
    {
      case POTION: type_as_str = "potion"; break;
      case SCROLL: type_as_str = "scroll"; break;
      case RING:   type_as_str = "ring"; break;
      case STICK:  type_as_str = "stick"; break;
    }
    mvwprintw(printscr, 1, 1, "No known %s", type_as_str.c_str());
  }

  move(orig_pos.y, orig_pos.x);
  wrefresh(printscr);
  delwin(printscr);
}

void
discovered(void)
{
  io_msg("for what type of objects do you want a list? (%c%c%c%c) ",
      POTION, SCROLL, RING, STICK);
  while (true)
  {
    char ch = io_readchar(true);
    touchwin(stdscr);
    refresh();
    switch (ch)
    {
      case POTION: discovered_by_type(ch, potion_info, NPOTIONS); break;
      case SCROLL: discovered_by_type(ch, scroll_info, NSCROLLS); break;
      case RING: discovered_by_type(ch, ring_info, NRINGS); break;
      case STICK: discovered_by_type(ch, wands_info, MAXSTICKS); break;
      default: io_msg_clear(); return;
    }
  }

  touchwin(stdscr);
  io_msg_clear();
}

<commit_msg>tiny cleanup<commit_after>#include <vector>
#include <string>
#include <sstream>

using namespace std;

#include "Coordinate.h"
#include "potions.h"
#include "scrolls.h"
#include "io.h"
#include "armor.h"
#include "pack.h"
#include "rings.h"
#include "misc.h"
#include "level.h"
#include "player.h"
#include "weapons.h"
#include "wand.h"
#include "os.h"
#include "options.h"
#include "rogue.h"

#include "things.h"

/* Only oi_prob is used */
vector<obj_info> things = {
/*   oi_name oi_prob oi_worth oi_guess oi_know */
    { "potion",	26,	0,	"",	false },
    { "scroll",	36,	0,	"",	false },
    { "food",	16,	0,	"",	false },
    { "weapon",	 7,	0,	"",	false },
    { "armor",	 7,	0,	"",	false },
    { "ring",	 4,	0,	"",	false },
    { "stick",	 4,	0,	"",	false },
};

string
inv_name(Item const* item, bool drop)
{
  stringstream buffer;

  switch (item->o_type)
  {
    case POTION: {
      char buf[MAXSTR];
      potion_description(item, buf);
      buffer << buf;
    } break;
    case RING: {
      char buf[MAXSTR];
      ring_description(item, buf);
      buffer << buf;
    } break;
    case STICK: {
      char buf[MAXSTR];
      wand_description(item, buf);
      buffer << buf;
    } break;
    case SCROLL: {
      char buf[MAXSTR];
      scroll_description(item, buf);
      buffer << buf;
    } break;
    case WEAPON: case AMMO: {
      char buf[MAXSTR];
      weapon_description(item, buf);
      buffer << buf;
    } break;
    case ARMOR: buffer << armor_description(item); break;
    case FOOD: {
      string obj_type = item->o_which == 1 ? "fruit" : "food ration";
      if (item->o_count == 1) {
        buffer << "A " << obj_type;
      } else {
        buffer << item->o_count << " " << obj_type;
      }
    } break;
    case AMULET: buffer << "The Amulet of Yendor"; break;
    case GOLD: buffer << item->o_goldval << " Gold pieces"; break;

    default:
      io_msg("You feel a disturbance in the force");
      buffer << "Something bizarre " << unctrl(static_cast<chtype>(item->o_type));
      break;
  }

  string return_value = buffer.str();
  return_value.at(0) = static_cast<char>(drop
      ? tolower(return_value.at(0))
      : toupper(return_value.at(0)));
  return return_value;
}

Item*
new_food(int which)
{
  /* Reset levels-without-food counter */
  levels_without_food = 0;

  Item* cur = new Item();
  cur->o_count = 1;
  cur->o_type = FOOD;
  switch (which)
  {
    case 0: case 1: cur->o_which = which; break;
    default: cur->o_which = os_rand_range(10) ? 0 : 1; break;
  }
  return cur;
}

Item*
new_amulet(void)
{
  Item* obj       = new Item();
  obj->o_damage  = {1, 2};
  obj->o_hurldmg = {1, 2};
  obj->o_type    = AMULET;

  return obj;
}

Item*
new_thing(void)
{
  /* Decide what kind of object it will be
   * If we haven't had food for a while, let it be food. */
  int r;
  if (levels_without_food > 3)
    r = 2;
  else
    r = static_cast<int>(pick_one(things, things.size()));

  Item* cur = nullptr;
  switch (r)
  {
    case 0: cur = potion_create(-1); break;
    case 1: cur = scroll_create(-1); break;
    case 2: cur = new_food(-1); break;
    case 3: cur = weapon_create(-1, true); break;
    case 4: cur = armor_create(-1, true); break;
    case 5: cur = ring_create(-1, true); break;
    case 6: cur = wand_create(-1); break;
    default:
      io_msg("Picked a bad kind of object (this should not happen)");
      io_wait_for_key(KEY_SPACE);
      break;
  }

  if (cur == nullptr) {
    throw runtime_error("curr is null");
  }
  if (cur->o_damage.sides < 0 || cur->o_damage.dices < 0) {
    throw runtime_error("cur->damage is negative");
  }
  if (cur->o_hurldmg.sides < 0 || cur->o_hurldmg.dices < 0) {
    throw runtime_error("cur->hurldmg is negative");
  }
  return cur;
}

size_t
pick_one(vector<obj_info>& start, size_t nitems)
{
  for (size_t rand = static_cast<size_t>(os_rand_range(100)), i = 0; i < nitems; ++i)
    if (rand < start.at(i).oi_prob)
      return i;
    else
      rand -= start.at(i).oi_prob;

  /* The functions should have returned by now */
  throw range_error("Probability was not in range");
}

/* list what the player has discovered of this type */
static void
discovered_by_type(char type, vector<obj_info>& info, size_t max_items)
{
  WINDOW *printscr = dupwin(stdscr);

  Coordinate orig_pos;
  getyx(stdscr, orig_pos.y, orig_pos.x);

  Item printable_object;
  memset(&printable_object, 0, sizeof(printable_object));
  printable_object.o_type = type;
  printable_object.o_flags = 0;
  printable_object.o_count = 1;

  int items_found = 0;
  for (size_t i = 0; i < max_items; ++i)
    if (info.at(i).oi_know || !info.at(i).oi_guess.empty())
    {
      printable_object.o_which = static_cast<int>(i);
      mvwprintw(printscr, ++items_found, 1,
                "%s", inv_name(&printable_object, false).c_str());
    }

  if (items_found == 0)
  {
    string type_as_str = nullptr;
    switch (type)
    {
      case POTION: type_as_str = "potion"; break;
      case SCROLL: type_as_str = "scroll"; break;
      case RING:   type_as_str = "ring"; break;
      case STICK:  type_as_str = "stick"; break;
    }
    mvwprintw(printscr, 1, 1, "No known %s", type_as_str.c_str());
  }

  move(orig_pos.y, orig_pos.x);
  wrefresh(printscr);
  delwin(printscr);
}

void
discovered(void)
{
  io_msg("for what type of objects do you want a list? (%c%c%c%c) ",
      POTION, SCROLL, RING, STICK);
  while (true)
  {
    char ch = io_readchar(true);
    touchwin(stdscr);
    refresh();
    switch (ch)
    {
      case POTION: discovered_by_type(ch, potion_info, NPOTIONS); break;
      case SCROLL: discovered_by_type(ch, scroll_info, NSCROLLS); break;
      case RING: discovered_by_type(ch, ring_info, NRINGS); break;
      case STICK: discovered_by_type(ch, wands_info, MAXSTICKS); break;
      default: io_msg_clear(); return;
    }
  }

  touchwin(stdscr);
  io_msg_clear();
}

<|endoftext|>