<commit_before>/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>

   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 Mumble Developers 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 FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "mumble_pch.hpp"

#include "About.h"

#include "Global.h"
#include "MainWindow.h"
#include "licenses.h"

AboutDialog::AboutDialog(QWidget *p) : QDialog(p) {
	setWindowTitle(tr("About Mumble"));

	QTabWidget *qtwTab = new QTabWidget(this);
	QVBoxLayout *vblMain = new QVBoxLayout(this);

	QTextEdit *qteLicense=new QTextEdit(qtwTab);
	qteLicense->setReadOnly(true);
	qteLicense->setPlainText(QLatin1String(licenseMumble));

	QTextBrowser *qtb3rdPartyLicense = new QTextBrowser(qtwTab);
	qtb3rdPartyLicense->setReadOnly(true);
	qtb3rdPartyLicense->setOpenExternalLinks(true);

	for(int i = 0; !licenses3rdParties[i].isEmpty(); ++i)
	{
		qtb3rdPartyLicense->append(QString::fromLatin1("
%1 (%2)

%3
")
				.arg(QString::fromLatin1(licenses3rdParties[i].name))
				.arg(QString::fromLatin1(licenses3rdParties[i].url))
				.arg(QString::fromLatin1(licenses3rdParties[i].license)));
	}

	qtb3rdPartyLicense->moveCursor(QTextCursor::Start);

	QWidget *about=new QWidget(qtwTab);

	QLabel *icon=new QLabel(about);
	icon->setPixmap(g.mw->qiIcon.pixmap(g.mw->qiIcon.actualSize(QSize(128, 128))));

	QLabel *text=new QLabel(about);
	text->setOpenExternalLinks(true);
	text->setText(tr(
		"
Mumble (%1)
"
		"
%3
"
		"
A voice-chat utility for gamers
"
		"
<tt>%2</tt>
"
	).arg(QLatin1String(MUMBLE_RELEASE))
	 .arg(QLatin1String("http://www.mumble.info/"))
	 .arg(QLatin1String("Copyright 2005-2015 The Mumble Developers")));
	QHBoxLayout *qhbl=new QHBoxLayout(about);
	qhbl->addWidget(icon);
	qhbl->addWidget(text);

	qtwTab->addTab(about, tr("&About Mumble"));
	qtwTab->addTab(qteLicense, tr("&License"));
	qtwTab->addTab(qtb3rdPartyLicense, tr("3rd &party licenses"));

	QPushButton *okButton = new QPushButton(tr("OK"), this);
	connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));

	vblMain->addWidget(qtwTab);
	vblMain->addWidget(okButton);
}
<commit_msg>About: update copyright year range to 2005-2016.<commit_after>/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>

   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 Mumble Developers 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 FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "mumble_pch.hpp"

#include "About.h"

#include "Global.h"
#include "MainWindow.h"
#include "licenses.h"

AboutDialog::AboutDialog(QWidget *p) : QDialog(p) {
	setWindowTitle(tr("About Mumble"));

	QTabWidget *qtwTab = new QTabWidget(this);
	QVBoxLayout *vblMain = new QVBoxLayout(this);

	QTextEdit *qteLicense=new QTextEdit(qtwTab);
	qteLicense->setReadOnly(true);
	qteLicense->setPlainText(QLatin1String(licenseMumble));

	QTextBrowser *qtb3rdPartyLicense = new QTextBrowser(qtwTab);
	qtb3rdPartyLicense->setReadOnly(true);
	qtb3rdPartyLicense->setOpenExternalLinks(true);

	for(int i = 0; !licenses3rdParties[i].isEmpty(); ++i)
	{
		qtb3rdPartyLicense->append(QString::fromLatin1("
%1 (%2)

%3
")
				.arg(QString::fromLatin1(licenses3rdParties[i].name))
				.arg(QString::fromLatin1(licenses3rdParties[i].url))
				.arg(QString::fromLatin1(licenses3rdParties[i].license)));
	}

	qtb3rdPartyLicense->moveCursor(QTextCursor::Start);

	QWidget *about=new QWidget(qtwTab);

	QLabel *icon=new QLabel(about);
	icon->setPixmap(g.mw->qiIcon.pixmap(g.mw->qiIcon.actualSize(QSize(128, 128))));

	QLabel *text=new QLabel(about);
	text->setOpenExternalLinks(true);
	text->setText(tr(
		"
Mumble (%1)
"
		"
%3
"
		"
A voice-chat utility for gamers
"
		"
<tt>%2</tt>
"
	).arg(QLatin1String(MUMBLE_RELEASE))
	 .arg(QLatin1String("http://www.mumble.info/"))
	 .arg(QLatin1String("Copyright 2005-2016 The Mumble Developers")));
	QHBoxLayout *qhbl=new QHBoxLayout(about);
	qhbl->addWidget(icon);
	qhbl->addWidget(text);

	qtwTab->addTab(about, tr("&About Mumble"));
	qtwTab->addTab(qteLicense, tr("&License"));
	qtwTab->addTab(qtb3rdPartyLicense, tr("3rd &party licenses"));

	QPushButton *okButton = new QPushButton(tr("OK"), this);
	connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));

	vblMain->addWidget(qtwTab);
	vblMain->addWidget(okButton);
}
<|endoftext|>


<commit_before>#include <random>
#include <chrono>
#include <algorithm>
#include <cmath>
#include <string>
#include <sstream>
#include <fstream>
#include <chrono>
#include <cstdlib>

#include "util.h"
#include "eval.h"

int main(int argc, const char *const argv[]) {
  constexpr size_t max_iterations = 50;
  constexpr float eb_no_max = 10;
  constexpr float eb_no_step = 0.1f;

  float alpha_start = (argc > 1) ? strtof(argv[1], nullptr) : 0.1f;
  float alpha_max = (argc > 2) ? strtof(argv[2], nullptr) : 1.0f;
  float alpha_step = (argc > 3) ? strtof(argv[3], nullptr) : 0.01f;

  std::cout << "Calculating from " << alpha_start << " to " << alpha_max
            << " in " << alpha_step << " steps" << std::endl;

  std::mt19937_64 generator(
      std::chrono::high_resolution_clock::now().time_since_epoch().count());

  bch code(5, 0x25, 7);
  // bch code(6, 0x45, 7);

  auto parameters = code.parameters();
  auto simulator = std::bind(evaluate, generator, std::placeholders::_1,
                             std::placeholders::_2, std::placeholders::_3,
                             std::get<0>(parameters), std::get<1>(parameters),
                             std::get<2>(parameters));

  std::ostringstream os;
  os << "alpha_" << alpha_start << "_" << std::get<0>(parameters) << "_"
     << std::get<1>(parameters) << "_" << std::get<2>(parameters) << ".dat";
  std::string fname(os.str());
  if (file_exists(fname)) {
    std::cerr << "File " << fname << " already exists." << std::endl;
    return -1;
  }

  std::ofstream file(fname, std::ofstream::out);
  std::cout << "Writing to file " << fname << std::endl;

  /* header */
  file << "eb_no ";
  for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
    std::ostringstream col_name;
    col_name << "ber_" << alpha * 1000 << " ";
    file << col_name.str();
  }
  file << std::endl;
  file << std::scientific;

  for (double eb_no = 0; eb_no < eb_no_max; eb_no += eb_no_step) {
    file << eb_no << " ";

    std::cout << "Calculating for E_b/N_0 = " << eb_no << std::endl;
    auto start = std::chrono::high_resolution_clock::now();
    for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
#if 0
      auto f = std::bind(nms<max_iterations, float, float>, std::ref(code.H()),
                         std::placeholders::_1, alpha);
#else
      auto f = std::bind(scms1_nms<max_iterations, float, float>,
                         std::cref(code.H()), std::placeholders::_1, alpha);
#endif
      const size_t N = iterations(eb_no);
      file << simulator(f, N, eb_no).ber() << " ";
      std::cout << eb_no << " " << alpha << " " << N << std::endl;
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto seconds =
        std::chrono::duration_cast<std::chrono::seconds>(end - start).count();

    std::cout << seconds << " s per iteration" << std::endl;
    file << std::endl;
  }
}
<commit_msg>Use wer for alpha optimization<commit_after>#include <random>
#include <chrono>
#include <algorithm>
#include <cmath>
#include <string>
#include <sstream>
#include <fstream>
#include <chrono>
#include <cstdlib>

#include "util.h"
#include "eval.h"

int main(int argc, const char *const argv[]) {
  constexpr size_t max_iterations = 50;
  constexpr float eb_no_max = 10;
  constexpr float eb_no_step = 0.1f;

  float alpha_start = (argc > 1) ? strtof(argv[1], nullptr) : 0.1f;
  float alpha_max = (argc > 2) ? strtof(argv[2], nullptr) : 1.0f;
  float alpha_step = (argc > 3) ? strtof(argv[3], nullptr) : 0.01f;

  std::cout << "Calculating from " << alpha_start << " to " << alpha_max
            << " in " << alpha_step << " steps" << std::endl;

  std::mt19937_64 generator(
      std::chrono::high_resolution_clock::now().time_since_epoch().count());

  bch code(5, 0x25, 7);
  // bch code(6, 0x45, 7);

  auto parameters = code.parameters();
  auto simulator = std::bind(evaluate, generator, std::placeholders::_1,
                             std::placeholders::_2, std::placeholders::_3,
                             std::get<0>(parameters), std::get<1>(parameters),
                             std::get<2>(parameters));

  std::ostringstream os;
  os << "alpha_" << alpha_start << "_" << std::get<0>(parameters) << "_"
     << std::get<1>(parameters) << "_" << std::get<2>(parameters) << ".dat";
  std::string fname(os.str());
  if (file_exists(fname)) {
    std::cerr << "File " << fname << " already exists." << std::endl;
    return -1;
  }

  std::ofstream file(fname, std::ofstream::out);
  std::cout << "Writing to file " << fname << std::endl;

  /* header */
  file << "eb_no ";
  for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
    std::ostringstream col_name;
    col_name << "wer_" << alpha * 1000 << " ";
    file << col_name.str();
  }
  file << std::endl;
  file << std::scientific;

  double wer = 0.5;
  for (double eb_no = 0; eb_no < eb_no_max; eb_no += eb_no_step) {
    file << eb_no << " ";

    std::cout << "Calculating for E_b/N_0 = " << eb_no << std::endl;
    auto start = std::chrono::high_resolution_clock::now();
    for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
#if 0
      auto f = std::bind(nms<max_iterations, float, float>, std::ref(code.H()),
                         std::placeholders::_1, alpha);
#else
      auto f = std::bind(scms1_nms<max_iterations, float, float>,
                         std::cref(code.H()), std::placeholders::_1, alpha);
#endif
      const size_t N = iterations(wer);
      wer = simulator(f, N, eb_no).wer();
      file << wer << " ";
      std::cout << eb_no << " " << alpha << " " << N << std::endl;
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto seconds =
        std::chrono::duration_cast<std::chrono::seconds>(end - start).count();

    std::cout << seconds << " s per iteration" << std::endl;
    file << std::endl;
  }
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osg/PagedLOD>
#include <osg/CullStack>
#include <osg/Notify>

#include <algorithm>

using namespace osg;

PagedLOD::PerRangeData::PerRangeData():
    _priorityOffset(0.0f),
    _priorityScale(1.0f),
    _timeStamp(0.0f) {}

PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd):
    _filename(prd._filename),
    _priorityOffset(prd._priorityOffset),
    _priorityScale(prd._priorityScale),
    _timeStamp(prd._timeStamp) {}

PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd)
{
    if (this==&prd) return *this;
    _filename = prd._filename;
    _priorityOffset = prd._priorityOffset;
    _priorityScale = prd._priorityScale;
    _timeStamp = prd._timeStamp;
    return *this;
}

PagedLOD::PagedLOD()
{
    _frameNumberOfLastTraversal = 0;
    _centerMode = USER_DEFINED_CENTER;
    _radius = -1;
    _numChildrenThatCannotBeExpired = 0;
}

PagedLOD::PagedLOD(const PagedLOD& plod,const CopyOp& copyop):
    LOD(plod,copyop),
    _frameNumberOfLastTraversal(plod._frameNumberOfLastTraversal),
    _numChildrenThatCannotBeExpired(plod._numChildrenThatCannotBeExpired),
    _perRangeDataList(plod._perRangeDataList)
{
}

void PagedLOD::setDatabasePath(const std::string& path)
{
    _databasePath = path;
    if (!_databasePath.empty())
    {
        char& lastCharacter = _databasePath[_databasePath.size()-1];
        const char unixSlash = '/';
        const char winSlash = '\\';

        if (lastCharacter==winSlash)
        {
            lastCharacter = unixSlash;
        }
        else if (lastCharacter!=unixSlash)
        {
            _databasePath += unixSlash;
        }

/*
        // make sure the last character is the appropriate slash
#ifdef WIN32
        if (lastCharacter==unixSlash)
        {
            lastCharacter = winSlash;
        }
        else if (lastCharacter!=winSlash)
        {
            _databasePath += winSlash;
        }
#else
        if (lastCharacter==winSlash)
        {
            lastCharacter = unixSlash;
        }
        else if (lastCharacter!=unixSlash)
        {
            _databasePath += unixSlash;
        }
#endif
*/
    }
}

void PagedLOD::traverse(NodeVisitor& nv)
{
    // set the frame number of the traversal so that external nodes can find out how active this
    // node is.
    if (nv.getFrameStamp()) setFrameNumberOfLastTraversal(nv.getFrameStamp()->getFrameNumber());

    double timeStamp = nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0;
    bool updateTimeStamp = nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR;

    switch(nv.getTraversalMode())
    {
        case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
            std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
            break;
        case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
        {
            float required_range = 0;
            if (_rangeMode==DISTANCE_FROM_EYE_POINT)
            {
                required_range = nv.getDistanceToEyePoint(getCenter(),true);
            }
            else
            {
                osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
                if (cullStack && cullStack->getLODScale()>0.0f)
                {
                    required_range = cullStack->clampedPixelSize(getBound()) / cullStack->getLODScale();
                }
                else
                {
                    // fallback to selecting the highest res tile by
                    // finding out the max range
                    for(unsigned int i=0;i<_rangeList.size();++i)
                    {
                        required_range = osg::maximum(required_range,_rangeList[i].first);
                    }
                }
            }

            int lastChildTraversed = -1;
            bool needToLoadChild = false;
            for(unsigned int i=0;i<_rangeList.size();++i)
            {
                if (_rangeList[i].first<=required_range && required_range<_rangeList[i].second)
                {
                    if (i<_children.size())
                    {
                        if (updateTimeStamp) _perRangeDataList[i]._timeStamp=timeStamp;

                        _children[i]->accept(nv);
                        lastChildTraversed = (int)i;
                    }
                    else
                    {
                        needToLoadChild = true;
                    }
                }
            }

            if (needToLoadChild)
            {
                unsigned int numChildren = _children.size();

                // select the last valid child.
                if (numChildren>0 && ((int)numChildren-1)!=lastChildTraversed)
                {
                    if (updateTimeStamp) _perRangeDataList[numChildren-1]._timeStamp=timeStamp;
                    _children[numChildren-1]->accept(nv);
                }

                // now request the loading of the next unloaded child.
                if (nv.getDatabaseRequestHandler() && numChildren<_perRangeDataList.size())
                {
                    // compute priority from where abouts in the required range the distance falls.
                    float priority = (_rangeList[numChildren].second-required_range)/(_rangeList[numChildren].second-_rangeList[numChildren].first);

                    // invert priority for PIXEL_SIZE_ON_SCREEN mode
                    if(_rangeMode==PIXEL_SIZE_ON_SCREEN)
                    {
                        priority = -priority;
                    }

                    // modify the priority according to the child's priority offset and scale.
                    priority = _perRangeDataList[numChildren]._priorityOffset + priority * _perRangeDataList[numChildren]._priorityScale;

                    if (_databasePath.empty())
                    {
                        nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
                    }
                    else
                    {
                        // prepend the databasePath to the child's filename.
                        nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
                    }
                }

            }

           break;
        }
        default:
            break;
    }
}

void PagedLOD::expandPerRangeDataTo(unsigned int pos)
{
    if (pos>=_perRangeDataList.size()) _perRangeDataList.resize(pos+1);
}

bool PagedLOD::addChild( Node *child )
{
    if (LOD::addChild(child))
    {
        expandPerRangeDataTo(_children.size()-1);
        return true;
    }
    return false;
}

bool PagedLOD::addChild(Node *child, float min, float max)
{
    if (LOD::addChild(child,min,max))
    {
        expandPerRangeDataTo(_children.size()-1);
        return true;
    }
    return false;
}

bool PagedLOD::addChild(Node *child, float min, float max,const std::string& filename, float priorityOffset, float priorityScale)
{
    if (LOD::addChild(child,min,max))
    {
        setFileName(_children.size()-1,filename);
        setPriorityOffset(_children.size()-1,priorityOffset);
        setPriorityScale(_children.size()-1,priorityScale);
        return true;
    }
    return false;
}

bool PagedLOD::removeChildren( unsigned int pos,unsigned int numChildrenToRemove)
{
    if (pos<_rangeList.size()) _rangeList.erase(_rangeList.begin()+pos, osg::minimum(_rangeList.begin()+(pos+numChildrenToRemove), _rangeList.end()) );
    if (pos<_perRangeDataList.size()) _perRangeDataList.erase(_perRangeDataList.begin()+pos, osg::minimum(_perRangeDataList.begin()+ (pos+numChildrenToRemove), _perRangeDataList.end()) );

    return Group::removeChildren(pos,numChildrenToRemove);
}

bool PagedLOD::removeExpiredChildren(double expiryTime,NodeList& removedChildren)
{
    if (_children.size()>_numChildrenThatCannotBeExpired)
    {
        if (!_perRangeDataList[_children.size()-1]._filename.empty() && _perRangeDataList[_children.size()-1]._timeStamp<expiryTime)
        {
            osg::Node* nodeToRemove = _children[_children.size()-1].get();
            removedChildren.push_back(nodeToRemove);
            return Group::removeChild(nodeToRemove);
        }
    }
    return false;
}
<commit_msg>Fixed expire of children to work with the new Group::removeChildren method.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osg/PagedLOD>
#include <osg/CullStack>
#include <osg/Notify>

#include <algorithm>

using namespace osg;

PagedLOD::PerRangeData::PerRangeData():
    _priorityOffset(0.0f),
    _priorityScale(1.0f),
    _timeStamp(0.0f) {}

PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd):
    _filename(prd._filename),
    _priorityOffset(prd._priorityOffset),
    _priorityScale(prd._priorityScale),
    _timeStamp(prd._timeStamp) {}

PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd)
{
    if (this==&prd) return *this;
    _filename = prd._filename;
    _priorityOffset = prd._priorityOffset;
    _priorityScale = prd._priorityScale;
    _timeStamp = prd._timeStamp;
    return *this;
}

PagedLOD::PagedLOD()
{
    _frameNumberOfLastTraversal = 0;
    _centerMode = USER_DEFINED_CENTER;
    _radius = -1;
    _numChildrenThatCannotBeExpired = 0;
}

PagedLOD::PagedLOD(const PagedLOD& plod,const CopyOp& copyop):
    LOD(plod,copyop),
    _frameNumberOfLastTraversal(plod._frameNumberOfLastTraversal),
    _numChildrenThatCannotBeExpired(plod._numChildrenThatCannotBeExpired),
    _perRangeDataList(plod._perRangeDataList)
{
}

void PagedLOD::setDatabasePath(const std::string& path)
{
    _databasePath = path;
    if (!_databasePath.empty())
    {
        char& lastCharacter = _databasePath[_databasePath.size()-1];
        const char unixSlash = '/';
        const char winSlash = '\\';

        if (lastCharacter==winSlash)
        {
            lastCharacter = unixSlash;
        }
        else if (lastCharacter!=unixSlash)
        {
            _databasePath += unixSlash;
        }

/*
        // make sure the last character is the appropriate slash
#ifdef WIN32
        if (lastCharacter==unixSlash)
        {
            lastCharacter = winSlash;
        }
        else if (lastCharacter!=winSlash)
        {
            _databasePath += winSlash;
        }
#else
        if (lastCharacter==winSlash)
        {
            lastCharacter = unixSlash;
        }
        else if (lastCharacter!=unixSlash)
        {
            _databasePath += unixSlash;
        }
#endif
*/
    }
}

void PagedLOD::traverse(NodeVisitor& nv)
{
    // set the frame number of the traversal so that external nodes can find out how active this
    // node is.
    if (nv.getFrameStamp()) setFrameNumberOfLastTraversal(nv.getFrameStamp()->getFrameNumber());

    double timeStamp = nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0;
    bool updateTimeStamp = nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR;

    switch(nv.getTraversalMode())
    {
        case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
            std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
            break;
        case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
        {
            float required_range = 0;
            if (_rangeMode==DISTANCE_FROM_EYE_POINT)
            {
                required_range = nv.getDistanceToEyePoint(getCenter(),true);
            }
            else
            {
                osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
                if (cullStack && cullStack->getLODScale()>0.0f)
                {
                    required_range = cullStack->clampedPixelSize(getBound()) / cullStack->getLODScale();
                }
                else
                {
                    // fallback to selecting the highest res tile by
                    // finding out the max range
                    for(unsigned int i=0;i<_rangeList.size();++i)
                    {
                        required_range = osg::maximum(required_range,_rangeList[i].first);
                    }
                }
            }

            int lastChildTraversed = -1;
            bool needToLoadChild = false;
            for(unsigned int i=0;i<_rangeList.size();++i)
            {
                if (_rangeList[i].first<=required_range && required_range<_rangeList[i].second)
                {
                    if (i<_children.size())
                    {
                        if (updateTimeStamp) _perRangeDataList[i]._timeStamp=timeStamp;

                        _children[i]->accept(nv);
                        lastChildTraversed = (int)i;
                    }
                    else
                    {
                        needToLoadChild = true;
                    }
                }
            }

            if (needToLoadChild)
            {
                unsigned int numChildren = _children.size();

                // select the last valid child.
                if (numChildren>0 && ((int)numChildren-1)!=lastChildTraversed)
                {
                    if (updateTimeStamp) _perRangeDataList[numChildren-1]._timeStamp=timeStamp;
                    _children[numChildren-1]->accept(nv);
                }

                // now request the loading of the next unloaded child.
                if (nv.getDatabaseRequestHandler() && numChildren<_perRangeDataList.size())
                {
                    // compute priority from where abouts in the required range the distance falls.
                    float priority = (_rangeList[numChildren].second-required_range)/(_rangeList[numChildren].second-_rangeList[numChildren].first);

                    // invert priority for PIXEL_SIZE_ON_SCREEN mode
                    if(_rangeMode==PIXEL_SIZE_ON_SCREEN)
                    {
                        priority = -priority;
                    }

                    // modify the priority according to the child's priority offset and scale.
                    priority = _perRangeDataList[numChildren]._priorityOffset + priority * _perRangeDataList[numChildren]._priorityScale;

                    if (_databasePath.empty())
                    {
                        nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
                    }
                    else
                    {
                        // prepend the databasePath to the child's filename.
                        nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
                    }
                }

            }

           break;
        }
        default:
            break;
    }
}

void PagedLOD::expandPerRangeDataTo(unsigned int pos)
{
    if (pos>=_perRangeDataList.size()) _perRangeDataList.resize(pos+1);
}

bool PagedLOD::addChild( Node *child )
{
    if (LOD::addChild(child))
    {
        expandPerRangeDataTo(_children.size()-1);
        return true;
    }
    return false;
}

bool PagedLOD::addChild(Node *child, float min, float max)
{
    if (LOD::addChild(child,min,max))
    {
        expandPerRangeDataTo(_children.size()-1);
        return true;
    }
    return false;
}

bool PagedLOD::addChild(Node *child, float min, float max,const std::string& filename, float priorityOffset, float priorityScale)
{
    if (LOD::addChild(child,min,max))
    {
        setFileName(_children.size()-1,filename);
        setPriorityOffset(_children.size()-1,priorityOffset);
        setPriorityScale(_children.size()-1,priorityScale);
        return true;
    }
    return false;
}

bool PagedLOD::removeChildren( unsigned int pos,unsigned int numChildrenToRemove)
{
    if (pos<_rangeList.size()) _rangeList.erase(_rangeList.begin()+pos, osg::minimum(_rangeList.begin()+(pos+numChildrenToRemove), _rangeList.end()) );
    if (pos<_perRangeDataList.size()) _perRangeDataList.erase(_perRangeDataList.begin()+pos, osg::minimum(_perRangeDataList.begin()+ (pos+numChildrenToRemove), _perRangeDataList.end()) );

    return Group::removeChildren(pos,numChildrenToRemove);
}

bool PagedLOD::removeExpiredChildren(double expiryTime,NodeList& removedChildren)
{
    if (_children.size()>_numChildrenThatCannotBeExpired)
    {
        if (!_perRangeDataList[_children.size()-1]._filename.empty() && _perRangeDataList[_children.size()-1]._timeStamp<expiryTime)
        {
            osg::Node* nodeToRemove = _children[_children.size()-1].get();
            removedChildren.push_back(nodeToRemove);
            return Group::removeChildren(_children.size()-1,1);
        }
    }
    return false;
}
<|endoftext|>


<commit_before>/*
 * This file is part of kpeople
 *
 * Copyright (C) 2010-2011 Collabora Ltd. <info@collabora.co.uk>
 *   @author George Goldberg <george.goldberg@collabora.co.uk>
 *   @author Martin Klapetek <martin.klapetek@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "person-cache.h"

#include <KDebug>
#include <KGlobal>
#include <KUrl>

#include <QtCore/QHash>

#include <Soprano/Query/QueryLanguage>
#include <Soprano/QueryResultIterator>
#include <Soprano/Model>

#include <Nepomuk/ResourceManager>
#include <Nepomuk/Variant>

#include <Nepomuk/Vocabulary/PIMO>
#include <Nepomuk/Vocabulary/NCO>
#include <Soprano/Vocabulary/NAO>

#include "person-cache-item.h"
#include "persons-model.h"
#include "persons-model-item.h"
#include "persons-model-contact-item.h"

/******************************** PersonCache::Private ********************************************/

class PersonCachePrivate {

protected:
    Q_DECLARE_PUBLIC(PersonCache);
    PersonCache * const q_ptr;

public:
    explicit PersonCachePrivate(PersonCache *q)
    : q_ptr(q)
    { }

    virtual ~PersonCachePrivate()
    { }

    QHash<QUrl, PersonCacheItem*> persons;
    QList<QUrl> allRequestedKeys;

    //FIXME: make it qpointer
    PersonsModel *model;
};

/****************************** Global Static Stuff ***********************************************/

class PersonCacheHelper {

public:
    PersonCacheHelper()
      : q(0)
    { }

    ~PersonCacheHelper()
    {
        delete q;
    }

    PersonCache *q;
};

K_GLOBAL_STATIC(PersonCacheHelper, s_globalPersonCache)

/******************************** PersonCache *****************************************************/

PersonCache *PersonCache::instance()
{
    if (!s_globalPersonCache->q) {
        new PersonCache;
    }

    return s_globalPersonCache->q;
}

PersonCache::PersonCache()
  : QObject(0),
    d_ptr(new PersonCachePrivate(this))
{
    kDebug();

    Q_ASSERT(!s_globalPersonCache->q);
    s_globalPersonCache->q = this;
}

PersonCache::~PersonCache()
{
    kDebug();

    delete d_ptr;
}

void PersonCache::startQuery()
{
    kDebug();

    QString nco_query = QString::fromUtf8("select distinct ?uri ?nao_prefLabel ?pimo_groundingOccurance ?nco_hasIMAccount"
                      "?nco_imNickname ?telepathy_statusType ?nco_imID ?nco_imAccountType ?nco_hasEmailAddress"
                      "?nao_prefSymbol ?telepathy_accountIdentifier ?nco_imStatus ?pimo_prefLabel ?pimo_prefSymbol"

                      "WHERE { ?uri a nco:Contact ."

                      "?uri                       nco:hasIMAccount            ?nco_hasIMAccount ."
                      "?nco_hasIMAccount          nco:imNickname              ?nco_imNickname ."
                      "?nco_hasIMAccount          telepathy:statusType        ?telepathy_statusType ."
                      "?nco_hasIMAccount          nco:imStatus                ?nco_imStatus ."
                      "?nco_hasIMAccount          nco:imID                    ?nco_imID ."
                      "?nco_hasIMAccount          nco:imAccountType           ?nco_imAccountType ."
                      "?nco_hasIMAccount          nco:isAccessedBy            ?nco_isAccessedBy ."
                      "?nco_isAccessedBy          telepathy:accountIdentifier ?telepathy_accountIdentifier ."

                      "OPTIONAL { ?pimo_groundingOccurance  pimo:groundingOccurrence    ?uri . }"
                      "OPTIONAL { ?pimo_groundingOccurance  nao:prefLabel      ?pimo_prefLabel . }"
                      "OPTIONAL { ?pimo_groundingOccurance  nao:prefSymbol     ?pimo_prefSymbol . }"

                      "OPTIONAL { ?uri            nao:prefLabel        ?nao_prefLabel . }"
                      "OPTIONAL { ?uri            nao:prefSymbol       ?nao_prefSymbol . }"
                      "OPTIONAL { ?uri            nco:hasEmailAddress  ?nco_hasEmailAddress . }"

    "}");

    QList<QUrl> list;
    list << Soprano::Vocabulary::NAO::prefLabel()
    << Soprano::Vocabulary::NAO::prefSymbol()
    << Nepomuk::Vocabulary::NCO::imNickname()
    << Nepomuk::Vocabulary::NCO::imAccountType()
    << Nepomuk::Vocabulary::NCO::imID()
    //                      << Nepomuk::Vocabulary::Telepathy::statusType()
    //                      << Nepomuk::Vocabulary::Telepathy::accountIdentifier()
    << QUrl(QLatin1String("http://nepomuk.kde.org/ontologies/2009/06/20/telepathy#statusType"))
    << QUrl(QLatin1String("http://nepomuk.kde.org/ontologies/2009/06/20/telepathy#accountIdentifier"))
    << Nepomuk::Vocabulary::NCO::imStatus()
    << Nepomuk::Vocabulary::NCO::hasEmailAddress();

    Soprano::QueryResultIterator it = Nepomuk::ResourceManager::instance()->mainModel()->executeQuery(nco_query,
                                                                                Soprano::Query::QueryLanguageSparql);

    QHash<QUrl, PersonCacheItem*> set;

    QString keyString;

    QHash<QUrl, QStandardItem *> personNodes;
    QHash<QStandardItem *, QList<QStandardItem *> > contactNodes;

    //FIXME: better way?
    QStandardItem *rootNode = 0;//new QStandardItem();
    QStandardItem *personNode;
    PersonsModelContactItem *contactNode;

    while(it.next()) {
        QUrl currentUri = it[QLatin1String("uri")].uri();
        QUrl pimoPersonUri = it[QLatin1String("pimo_groundingOccurance")].uri();

        if (!pimoPersonUri.isEmpty()) {
            if (personNodes.keys().contains(pimoPersonUri)) {
                personNode = personNodes.value(pimoPersonUri);
//                 kDebug() << "Selecting existing person" << currentUri << pimoPersonUri;
            } else {
                personNode = new PersonsModelItem(pimoPersonUri);
                personNodes.insert(pimoPersonUri, personNode);
//                 kDebug() << "Inserting new person" << currentUri << pimoPersonUri;
            }
        } else {
            personNode = rootNode;
            kDebug() << "Not a person" << currentUri << pimoPersonUri;
        }

        contactNode = new PersonsModelContactItem(it[QLatin1String("nao_prefLabel")].toString(), QLatin1String("id"), PersonsModel::Email);

        Q_FOREACH(const QUrl &keyUri, list) {
            keyString = keyUri.toString();
            //convert every key to correspond to the nepomuk bindings
            //FIXME: get this method out of the loop, it repeats too many times for nothing
            keyString = keyString.right(keyString.length() - keyString.lastIndexOf(QLatin1Char('/')) - 1).replace(QLatin1Char('#'), QLatin1Char('_'));

            contactNode->addData(keyUri, it[keyString].toString());
        }

        if (!contactNode->data(Nepomuk::Vocabulary::NCO::imID()).isEmpty()) {
            contactNode->setType(PersonsModel::IM);
        }
        if (!contactNode->data(Nepomuk::Vocabulary::NCO::hasEmailAddress()).isEmpty()) {
            contactNode->setType(PersonsModel::Email);
        }

        contactNodes.insert(personNode, QList<QStandardItem*>() << contactNode);
    }

    d_ptr->persons.unite(set);

    // FIXME: Connect up signals/slots so that when the nepomuk context signals something has
    //        happened we relay it to the model

    emit contactsFetched(personNodes, contactNodes);
}

void PersonCache::onNewPersonCreated(Nepomuk::Resource res, QList<QUrl> types)
{
    Q_D(PersonCache);

    bool newPerson = false;
    PersonCacheItem *person;
    if (d->persons.contains(res.resourceUri())) {
        person = d->persons.value(res.resourceUri());
    } else {
        person = new PersonCacheItem(res.resourceUri());
        newPerson = true;
    }

    kDebug() << "New person created in Nepomuk";

    Q_FOREACH (const QUrl &keyUri, types) {
        if (res.hasProperty(keyUri)) {
            if (res.property(keyUri).isString()) {
                person->addData(keyUri, res.property(keyUri).toString());
            } else if (res.property(keyUri).isStringList()) {
                person->addData(keyUri, res.property(keyUri).toStringList());
            }
        }
    }

    if (newPerson) {
        d->persons.insert(res.resourceUri(), person);
    }

    emit personAddedToCache(person);
}

void PersonCache::onPersonRemoved()
{
    //FIXME: implement me
}

void PersonCache::onPersonPropertyChanged(Nepomuk::Resource res, Nepomuk::Types::Property property, QVariant value)
{
    //FIXME: implement me
}

#include "person-cache.moc"
<commit_msg>Adapt to PersonsModelContactItem<commit_after>/*
 * This file is part of kpeople
 *
 * Copyright (C) 2010-2011 Collabora Ltd. <info@collabora.co.uk>
 *   @author George Goldberg <george.goldberg@collabora.co.uk>
 *   @author Martin Klapetek <martin.klapetek@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "person-cache.h"

#include <KDebug>
#include <KGlobal>
#include <KUrl>

#include <QtCore/QHash>

#include <Soprano/Query/QueryLanguage>
#include <Soprano/QueryResultIterator>
#include <Soprano/Model>

#include <Nepomuk/ResourceManager>
#include <Nepomuk/Variant>

#include <Nepomuk/Vocabulary/PIMO>
#include <Nepomuk/Vocabulary/NCO>
#include <Soprano/Vocabulary/NAO>

#include "person-cache-item.h"
#include "persons-model.h"
#include "persons-model-item.h"
#include "persons-model-contact-item.h"

/******************************** PersonCache::Private ********************************************/

class PersonCachePrivate {

protected:
    Q_DECLARE_PUBLIC(PersonCache);
    PersonCache * const q_ptr;

public:
    explicit PersonCachePrivate(PersonCache *q)
    : q_ptr(q)
    { }

    virtual ~PersonCachePrivate()
    { }

    QHash<QUrl, PersonCacheItem*> persons;
    QList<QUrl> allRequestedKeys;

    //FIXME: make it qpointer
    PersonsModel *model;
};

/****************************** Global Static Stuff ***********************************************/

class PersonCacheHelper {

public:
    PersonCacheHelper()
      : q(0)
    { }

    ~PersonCacheHelper()
    {
        delete q;
    }

    PersonCache *q;
};

K_GLOBAL_STATIC(PersonCacheHelper, s_globalPersonCache)

/******************************** PersonCache *****************************************************/

PersonCache *PersonCache::instance()
{
    if (!s_globalPersonCache->q) {
        new PersonCache;
    }

    return s_globalPersonCache->q;
}

PersonCache::PersonCache()
  : QObject(0),
    d_ptr(new PersonCachePrivate(this))
{
    kDebug();

    Q_ASSERT(!s_globalPersonCache->q);
    s_globalPersonCache->q = this;
}

PersonCache::~PersonCache()
{
    kDebug();

    delete d_ptr;
}

void PersonCache::startQuery()
{
    kDebug();

    QString nco_query = QString::fromUtf8("select distinct ?uri ?nao_prefLabel ?pimo_groundingOccurance ?nco_hasIMAccount"
                      "?nco_imNickname ?telepathy_statusType ?nco_imID ?nco_imAccountType ?nco_hasEmailAddress"
                      "?nao_prefSymbol ?telepathy_accountIdentifier ?nco_imStatus ?pimo_prefLabel ?pimo_prefSymbol"

                      "WHERE { ?uri a nco:Contact ."

                      "?uri                       nco:hasIMAccount            ?nco_hasIMAccount ."
                      "?nco_hasIMAccount          nco:imNickname              ?nco_imNickname ."
                      "?nco_hasIMAccount          telepathy:statusType        ?telepathy_statusType ."
                      "?nco_hasIMAccount          nco:imStatus                ?nco_imStatus ."
                      "?nco_hasIMAccount          nco:imID                    ?nco_imID ."
                      "?nco_hasIMAccount          nco:imAccountType           ?nco_imAccountType ."
                      "?nco_hasIMAccount          nco:isAccessedBy            ?nco_isAccessedBy ."
                      "?nco_isAccessedBy          telepathy:accountIdentifier ?telepathy_accountIdentifier ."

                      "OPTIONAL { ?pimo_groundingOccurance  pimo:groundingOccurrence    ?uri . }"
                      "OPTIONAL { ?pimo_groundingOccurance  nao:prefLabel      ?pimo_prefLabel . }"
                      "OPTIONAL { ?pimo_groundingOccurance  nao:prefSymbol     ?pimo_prefSymbol . }"

                      "OPTIONAL { ?uri            nao:prefLabel        ?nao_prefLabel . }"
                      "OPTIONAL { ?uri            nao:prefSymbol       ?nao_prefSymbol . }"
                      "OPTIONAL { ?uri            nco:hasEmailAddress  ?nco_hasEmailAddress . }"

    "}");

    QList<QUrl> list;
    list << Soprano::Vocabulary::NAO::prefLabel()
    << Soprano::Vocabulary::NAO::prefSymbol()
    << Nepomuk::Vocabulary::NCO::imNickname()
    << Nepomuk::Vocabulary::NCO::imAccountType()
    << Nepomuk::Vocabulary::NCO::imID()
    //                      << Nepomuk::Vocabulary::Telepathy::statusType()
    //                      << Nepomuk::Vocabulary::Telepathy::accountIdentifier()
    << QUrl(QLatin1String("http://nepomuk.kde.org/ontologies/2009/06/20/telepathy#statusType"))
    << QUrl(QLatin1String("http://nepomuk.kde.org/ontologies/2009/06/20/telepathy#accountIdentifier"))
    << Nepomuk::Vocabulary::NCO::imStatus()
    << Nepomuk::Vocabulary::NCO::hasEmailAddress();

    Soprano::QueryResultIterator it = Nepomuk::ResourceManager::instance()->mainModel()->executeQuery(nco_query,
                                                                                Soprano::Query::QueryLanguageSparql);

    QHash<QUrl, PersonCacheItem*> set;

    QString keyString;

    QHash<QUrl, QStandardItem *> personNodes;
    QHash<QStandardItem *, QList<QStandardItem *> > contactNodes;

    //FIXME: better way?
    QStandardItem *rootNode = 0;//new QStandardItem();
    QStandardItem *personNode;
    PersonsModelContactItem *contactNode;

    while(it.next()) {
        QUrl currentUri = it[QLatin1String("uri")].uri();
        QUrl pimoPersonUri = it[QLatin1String("pimo_groundingOccurance")].uri();

        if (!pimoPersonUri.isEmpty()) {
            if (personNodes.keys().contains(pimoPersonUri)) {
                personNode = personNodes.value(pimoPersonUri);
//                 kDebug() << "Selecting existing person" << currentUri << pimoPersonUri;
            } else {
                personNode = new PersonsModelItem(pimoPersonUri);
                personNodes.insert(pimoPersonUri, personNode);
//                 kDebug() << "Inserting new person" << currentUri << pimoPersonUri;
            }
        } else {
            personNode = rootNode;
            kDebug() << "Not a person" << currentUri << pimoPersonUri;
        }

        contactNode = new PersonsModelContactItem(currentUri, it[QLatin1String("nao_prefLabel")].toString(), QLatin1String("id"), PersonsModel::Email);

        Q_FOREACH(const QUrl &keyUri, list) {
            keyString = keyUri.toString();
            //convert every key to correspond to the nepomuk bindings
            //FIXME: get this method out of the loop, it repeats too many times for nothing
            keyString = keyString.right(keyString.length() - keyString.lastIndexOf(QLatin1Char('/')) - 1).replace(QLatin1Char('#'), QLatin1Char('_'));

            contactNode->addData(keyUri, it[keyString].toString());
        }

        if (!contactNode->dataValue(Nepomuk::Vocabulary::NCO::imID()).isEmpty()) {
            contactNode->setType(PersonsModel::IM);
        }
        if (!contactNode->dataValue(Nepomuk::Vocabulary::NCO::hasEmailAddress()).isEmpty()) {
            contactNode->setType(PersonsModel::Email);
        }

        contactNodes.insert(personNode, QList<QStandardItem*>() << contactNode);
    }

    d_ptr->persons.unite(set);

    // FIXME: Connect up signals/slots so that when the nepomuk context signals something has
    //        happened we relay it to the model

    emit contactsFetched(personNodes, contactNodes);
}

void PersonCache::onNewPersonCreated(Nepomuk::Resource res, QList<QUrl> types)
{
    Q_D(PersonCache);

    bool newPerson = false;
    PersonCacheItem *person;
    if (d->persons.contains(res.resourceUri())) {
        person = d->persons.value(res.resourceUri());
    } else {
        person = new PersonCacheItem(res.resourceUri());
        newPerson = true;
    }

    kDebug() << "New person created in Nepomuk";

    Q_FOREACH (const QUrl &keyUri, types) {
        if (res.hasProperty(keyUri)) {
            if (res.property(keyUri).isString()) {
                person->addData(keyUri, res.property(keyUri).toString());
            } else if (res.property(keyUri).isStringList()) {
                person->addData(keyUri, res.property(keyUri).toStringList());
            }
        }
    }

    if (newPerson) {
        d->persons.insert(res.resourceUri(), person);
    }

    emit personAddedToCache(person);
}

void PersonCache::onPersonRemoved()
{
    //FIXME: implement me
}

void PersonCache::onPersonPropertyChanged(Nepomuk::Resource res, Nepomuk::Types::Property property, QVariant value)
{
    //FIXME: implement me
}

#include "person-cache.moc"
<|endoftext|>


<commit_before>/* Copyright (c) 2012-18, Robert J. Hansen <rob@hansen.engineering>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "common.hpp"
#include <boost/program_options.hpp>
#include <iostream>

using boost::program_options::error;
using boost::program_options::notify;
using boost::program_options::options_description;
using boost::program_options::parse_command_line;
using boost::program_options::store;
using boost::program_options::value;
using boost::program_options::variables_map;
using std::array;
using std::cerr;
using std::cout;
using std::fill;
using std::string;

void parse_options(int argc, char** argv)
{
    options_description options { "nsrllookup options" };
    options.add_options()("help,h", "Show this help screen")(
        "version,v", "Show version information")(
        "bug-reports,b", "Show bug reporting information")(
        "known,k", "Show only RDS hits")("unknown,u",
        "Show only RDS misses (default)")(
        "server,s", value<string>()->default_value("nsrllookup.com"),
        "nsrlsvr instance to use")(
        "port,p", value<string>()->default_value("9120"), "port to connect on");
    variables_map vm;

    try {
        store(parse_command_line(argc, argv, options), vm);
        notify(vm);
    } catch (error& e) {
        cout << "Error: " << e.what() << "\n";
        bomb(-1);
    }

    if (vm.count("help")) {
        cout << options << "\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("version")) {
        cout << "nsrllookup " << PACKAGE_VERSION << "\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("bug-reports")) {
        cout << "To file a bug report, visit " << PACKAGE_URL << "\n"
             << "(or email " << PACKAGE_BUGREPORT << ")\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("known") && vm.count("unknown")) {
        cout << "Error: the known and unknown flags are mutually exclusive.\n";
        bomb(-1);
    }
    SCORE_HITS = static_cast<bool>(vm.count("known"));
    SERVER = vm["server"].as<string>();
    PORT = vm["port"].as<string>();
}
<commit_msg>Require Windows 7 or later.<commit_after>/* Copyright (c) 2012-18, Robert J. Hansen <rob@hansen.engineering>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "common.hpp"
#include <boost/program_options.hpp>
#include <iostream>

using boost::program_options::error;
using boost::program_options::notify;
using boost::program_options::options_description;
using boost::program_options::parse_command_line;
using boost::program_options::store;
using boost::program_options::value;
using boost::program_options::variables_map;
using std::array;
using std::cerr;
using std::cout;
using std::fill;
using std::string;

#ifdef WINDOWS
#define _WIN32_WINNT 0x0601
#endif

void parse_options(int argc, char** argv)
{
    options_description options { "nsrllookup options" };
    options.add_options()("help,h", "Show this help screen")(
        "version,v", "Show version information")(
        "bug-reports,b", "Show bug reporting information")(
        "known,k", "Show only RDS hits")("unknown,u",
        "Show only RDS misses (default)")(
        "server,s", value<string>()->default_value("nsrllookup.com"),
        "nsrlsvr instance to use")(
        "port,p", value<string>()->default_value("9120"), "port to connect on");
    variables_map vm;

    try {
        store(parse_command_line(argc, argv, options), vm);
        notify(vm);
    } catch (error& e) {
        cout << "Error: " << e.what() << "\n";
        bomb(-1);
    }

    if (vm.count("help")) {
        cout << options << "\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("version")) {
        cout << "nsrllookup " << PACKAGE_VERSION << "\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("bug-reports")) {
        cout << "To file a bug report, visit " << PACKAGE_URL << "\n"
             << "(or email " << PACKAGE_BUGREPORT << ")\n";
        bomb(EXIT_SUCCESS);
    }
    if (vm.count("known") && vm.count("unknown")) {
        cout << "Error: the known and unknown flags are mutually exclusive.\n";
        bomb(-1);
    }
    SCORE_HITS = static_cast<bool>(vm.count("known"));
    SERVER = vm["server"].as<string>();
    PORT = vm["port"].as<string>();
}
<|endoftext|>


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

#include "InitShares.h"
#include <fstream>

using namespace std;

template <typename T>
boost::program_options::typed_value<T>* make_value(T* store_to)
{
  return boost::program_options::value<T>(store_to);
}

user make_user( const std::string& user_group_share )
{
  std::vector< std::string > tokens;
  boost::split( tokens, user_group_share, boost::is_any_of( ":" ) );

  if ( 3 != tokens.size() )
  {
     using boost::program_options::validation_error;
     throw validation_error(validation_error::invalid_option_value,
                            "users.user",
                            user_group_share);
  }
  return user(boost::lexical_cast<unsigned short>(tokens[0]),
	      boost::lexical_cast<unsigned short>(tokens[1]),
              boost::lexical_cast<unsigned short>(tokens[2]));
}

bool InitShares::load_shares(){

    std::vector<std::string> user_configs;

    cout << "Loading initial shares..." << endl;
    po::options_description desc("Allowed options");

    desc.add_options()
		("users.user", make_value(&user_configs), "initial shares")
		;

    /// Read the initial shares file
    ifstream settings_file(shares_file.c_str());

    /// Clear the map
    vm = po::variables_map();

    try{
        po::store(po::parse_shares_file(initset_file , desc), vm);
    } catch(const exception& re){
        cerr << "Error: " << re.what() << endl;
        return false;
    }

    po::notify(vm);

  std::vector<user> users;
  std::transform(user_configs.begin(), user_configs.end(),
                  std::back_inserter(users),
                  make_user);

    return true;
}

const char * FassInitShares::shares_name="shares.conf";

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

#include "InitShares.h"

#include <fstream>

template <typename T>
boost::program_options::typed_value<T>* make_value(T* store_to) {
  return boost::program_options::value<T>(store_to);
}

user make_user( const std::string& user_group_share ) {
  std::vector< std::string > tokens;
  boost::split( tokens, user_group_share, boost::is_any_of( ":" ) );

  if ( 3 != tokens.size() ) {
     using boost::program_options::validation_error;
     throw validation_error(validation_error::invalid_option_value,
                            "users.user",
                            user_group_share);
  }
  return user(boost::lexical_cast<int16_t>(tokens[0]),
	      boost::lexical_cast<int16_t>(tokens[1]),
              boost::lexical_cast<int16_t>(tokens[2]));
}

bool InitShares::load_shares() {
    std::vector<std::string> user_configs;

    cout << "Loading initial shares..." << endl;
    po::options_description desc("Allowed options");

    desc.add_options()
		("users.user", make_value(&user_configs), "initial shares");

    /// Read the initial shares file
    ifstream settings_file(shares_file.c_str());

    /// Clear the map
    vm = po::variables_map();

    try {
        po::store(po::parse_shares_file(initset_file, desc), vm);
    } catch(const exception& re) {
        std::cerr << "Error: " << re.what() << std::endl;
        return false;
    }

    po::notify(vm);

  std::vector<user> users;
  std::transform(user_configs.begin(), user_configs.end(),
                  std::back_inserter(users),
                  make_user);

    return true;
}

const char * FassInitShares::shares_name = "shares.conf";

<|endoftext|>


<commit_before>/*
  Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <errno.h>

#include <string>
#include <vector>

#include "fs.hpp"
#include "fs_path.hpp"
#include "policy.hpp"

using std::string;
using std::vector;
using std::size_t;
using mergerfs::Category;

static
int
_epmfs_create(const vector<string>  &basepaths,
              const char            *fusepath,
              vector<const string*> &paths)
{
  string fullpath;
  size_t epmfs;
  const string *epmfsbasepath;

  epmfs = 0;
  epmfsbasepath = NULL;
  for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
    {
      bool readonly;
      size_t spaceavail;
      const string *basepath = &basepaths[i];

      fs::path::make(basepath,fusepath,fullpath);

      if(!fs::exists(fullpath))
        continue;
      if(!fs::info(*basepath,readonly,spaceavail))
        continue;
      if(readonly)
        continue;
      if(spaceavail < epmfs)
        continue;

      epmfs = spaceavail;
      epmfsbasepath = basepath;
    }

  if(epmfsbasepath == NULL)
    return POLICY_FAIL_ENOENT;

  paths.push_back(epmfsbasepath);

  return POLICY_SUCCESS;
}

static
int
_epmfs_other(const vector<string>  &basepaths,
             const char            *fusepath,
             vector<const string*> &paths)
{
  string fullpath;
  size_t epmfs;
  const string *epmfsbasepath;

  epmfs = 0;
  epmfsbasepath = NULL;
  for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
    {
      size_t spaceavail;
      const string *basepath = &basepaths[i];

      fs::path::make(basepath,fusepath,fullpath);

      if(!fs::exists(fullpath))
        continue;
      if(!fs::spaceavail(*basepath,spaceavail))
        continue;
      if(spaceavail < epmfs)
        continue;

      epmfs = spaceavail;
      epmfsbasepath = basepath;
    }

  if(epmfsbasepath == NULL)
    return POLICY_FAIL_ENOENT;

  paths.push_back(epmfsbasepath);

  return POLICY_SUCCESS;
}

static
int
_epmfs(const Category::Enum::Type  type,
       const vector<string>       &basepaths,
       const char                 *fusepath,
       vector<const string*>     &paths)
{
  if(type == Category::Enum::create)
    return _epmfs_create(basepaths,fusepath,paths);

  return _epmfs_other(basepaths,fusepath,paths);
}

namespace mergerfs
{
  int
  Policy::Func::epmfs(const Category::Enum::Type  type,
                      const vector<string>       &basepaths,
                      const char                 *fusepath,
                      const size_t                minfreespace,
                      vector<const string*>     &paths)
  {
    int rv;

    rv = _epmfs(type,basepaths,fusepath,paths);
    if(POLICY_FAILED(rv))
      rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);

    return rv;
  }
}
<commit_msg>re-add minfreespace check to epmfs policy<commit_after>/*
  Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <errno.h>

#include <limits>
#include <string>
#include <vector>

#include "fs.hpp"
#include "fs_path.hpp"
#include "policy.hpp"

using std::string;
using std::vector;
using std::size_t;
using mergerfs::Category;

static
int
_epmfs_create(const vector<string>  &basepaths,
              const char            *fusepath,
              const size_t           minfreespace,
              vector<const string*> &paths)
{
  string fullpath;
  size_t epmfs;
  const string *epmfsbasepath;

  epmfs = std::numeric_limits<size_t>::min();
  epmfsbasepath = NULL;
  for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
    {
      bool readonly;
      size_t spaceavail;
      const string *basepath = &basepaths[i];

      fs::path::make(basepath,fusepath,fullpath);

      if(!fs::exists(fullpath))
        continue;
      if(!fs::info(*basepath,readonly,spaceavail))
        continue;
      if(readonly)
        continue;
      if(spaceavail < minfreespace)
        continue;
      if(spaceavail < epmfs)
        continue;

      epmfs = spaceavail;
      epmfsbasepath = basepath;
    }

  if(epmfsbasepath == NULL)
    return POLICY_FAIL_ENOENT;

  paths.push_back(epmfsbasepath);

  return POLICY_SUCCESS;
}

static
int
_epmfs_other(const vector<string>  &basepaths,
             const char            *fusepath,
             vector<const string*> &paths)
{
  string fullpath;
  size_t epmfs;
  const string *epmfsbasepath;

  epmfs = 0;
  epmfsbasepath = NULL;
  for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
    {
      size_t spaceavail;
      const string *basepath = &basepaths[i];

      fs::path::make(basepath,fusepath,fullpath);

      if(!fs::exists(fullpath))
        continue;
      if(!fs::spaceavail(*basepath,spaceavail))
        continue;
      if(spaceavail < epmfs)
        continue;

      epmfs = spaceavail;
      epmfsbasepath = basepath;
    }

  if(epmfsbasepath == NULL)
    return POLICY_FAIL_ENOENT;

  paths.push_back(epmfsbasepath);

  return POLICY_SUCCESS;
}

static
int
_epmfs(const Category::Enum::Type  type,
       const vector<string>       &basepaths,
       const char                 *fusepath,
       const size_t                minfreespace,
       vector<const string*>      &paths)
{
  if(type == Category::Enum::create)
    return _epmfs_create(basepaths,fusepath,minfreespace,paths);

  return _epmfs_other(basepaths,fusepath,paths);
}

namespace mergerfs
{
  int
  Policy::Func::epmfs(const Category::Enum::Type  type,
                      const vector<string>       &basepaths,
                      const char                 *fusepath,
                      const size_t                minfreespace,
                      vector<const string*>     &paths)
  {
    int rv;

    rv = _epmfs(type,basepaths,fusepath,minfreespace,paths);
    if(POLICY_FAILED(rv))
      rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);

    return rv;
  }
}
<|endoftext|>


<commit_before>#include "qtumDGP.h"

std::vector<ResultExecute> QtumDGP::callContract(const dev::Address& addrContract, std::vector<unsigned char> opcode){
    CBlock block;
    CMutableTransaction tx;
    dev::u256 gasLimit(DEFAULT_BLOCK_GASLIMIT - 1); // MAX_MONEY
    dev::Address senderAddress("ffffffffffffffffffffffffffffffffffffffff");
    tx.vout.push_back(CTxOut(0, CScript() << OP_DUP << OP_HASH160 << senderAddress.asBytes() << OP_EQUALVERIFY << OP_CHECKSIG));
    block.vtx.push_back(MakeTransactionRef(CTransaction(tx)));

    QtumTransaction callTransaction(0, 1, gasLimit, addrContract, opcode, dev::u256(0));
    callTransaction.forceSender(senderAddress);

    ByteCodeExec exec(block, std::vector<QtumTransaction>(1, callTransaction));
    exec.performByteCode(dev::eth::Permanence::Reverted);
    return exec.getResult();
}

dev::eth::EVMSchedule QtumDGP::getGasSchedule(unsigned int blockHeight){
    clear();
    dev::eth::EVMSchedule schedule = dev::eth::EIP158Schedule;
    if(initStorages(GasScheduleDGP, blockHeight, ParseHex("26fadbe2"))){
        schedule = createEVMSchedule();
    }
    return schedule;
}

uint32_t QtumDGP::getUint32FromDGP(unsigned int blockHeight, const dev::Address& contract, std::vector<unsigned char> data){
    uint32_t value = 0;
    if(initStorages(contract, blockHeight, data)){
        if(!dgpevm){
            parseStorageOneUint32(value);
        } else {
            parseDataOneUint32(value);
        }
    }
    return value;
}

uint32_t QtumDGP::getBlockSize(unsigned int blockHeight){
    clear();
    uint32_t result = defaultBlockSizeDGP;
    uint32_t blockSize = getUint32FromDGP(blockHeight, BlockSizeDGP, ParseHex("92ac3c62"));
    if(blockSize <= maxBlockSizeDGP && blockSize >= minBlockSizeDGP){
        result = blockSize;
    }
    return result;
}

uint32_t QtumDGP::getMinGasPrice(unsigned int blockHeight){
    clear();
    uint32_t result = defaultMinGasPriceDGP;
    uint32_t minGasPrice = getUint32FromDGP(blockHeight, GasPriceDGP, ParseHex("3fb58819"));
    if(minGasPrice <= maxMinGasPriceDGP && minGasPrice >= minMinGasPriceDGP){
        result = minGasPrice;
    }
    return result;
}

uint32_t QtumDGP::getBlockGasLimit(unsigned int blockHeight){
    clear();
    uint32_t result = defaultBlockGasLimitDGP;
    uint32_t blockGasLimit = getUint32FromDGP(blockHeight, BlockGasLimitDGP, ParseHex("2cc8377d"));
    if(blockGasLimit <= maxBlockGasLimitDGP && blockGasLimit >= minBlockGasLimitDGP){
        result = blockGasLimit;
    }
    return result;
}

bool QtumDGP::initStorages(const dev::Address& addr, unsigned int blockHeight, std::vector<unsigned char> data){
    initStorageDGP(addr);
    createParamsInstance();
    dev::Address address = getAddressForBlock(blockHeight);
    if(address != dev::Address()){
        if(!dgpevm){
            initStorageTemplate(address);
        } else {
            initDataTemplate(address, data);
        }
        return true;
    }
    return false;
}

void QtumDGP::initStorageDGP(const dev::Address& addr){
    storageDGP = state->storage(addr);
}

void QtumDGP::initStorageTemplate(const dev::Address& addr){
    storageTemplate = state->storage(addr);
}

void QtumDGP::initDataTemplate(const dev::Address& addr, std::vector<unsigned char>& data){
    dataTemplate = callContract(addr, data)[0].execRes.output;
}

void QtumDGP::createParamsInstance(){
    dev::h256 paramsInstanceHash = sha3(dev::h256("0000000000000000000000000000000000000000000000000000000000000000"));
    if(storageDGP.count(paramsInstanceHash)){
        dev::u256 paramsInstanceSize = storageDGP.find(paramsInstanceHash)->second.second;
        for(size_t i = 0; i < size_t(paramsInstanceSize); i++){
            std::pair<unsigned int, dev::Address> params;
            params.first = uint64_t(storageDGP.find(sha3(paramsInstanceHash))->second.second);
            ++paramsInstanceHash;
            params.second = dev::right160(dev::h256(storageDGP.find(sha3(paramsInstanceHash))->second.second));
            ++paramsInstanceHash;
            paramsInstance.push_back(params);
        }
    }
}

dev::Address QtumDGP::getAddressForBlock(unsigned int blockHeight){
    for(auto i = paramsInstance.rbegin(); i != paramsInstance.rend(); i++){
        if(i->first <= blockHeight)
            return i->second;
    }
    return dev::Address();
}

void QtumDGP::parseStorageScheduleContract(std::vector<uint32_t>& uint32Values){
    std::vector<std::pair<dev::u256, dev::u256>> data;
    for(size_t i = 0; i < 5; i++){
        dev::h256 gasScheduleHash = sha3(dev::h256(dev::u256(i)));
        if(storageTemplate.count(gasScheduleHash)){
            dev::u256 key = storageTemplate.find(gasScheduleHash)->second.first;
            dev::u256 value = storageTemplate.find(gasScheduleHash)->second.second;
            data.push_back(std::make_pair(key, value));
        }
    }

    std::sort(data.begin(), data.end(), [&data](std::pair<dev::u256, dev::u256>& a, std::pair<dev::u256, dev::u256>& b){
        return a.first < b.first;
    });

    for(std::pair<dev::u256, dev::u256> d : data){
        dev::u256 value = d.second;
        for(size_t i = 0; i < 4; i++){
            uint64_t uint64Value = uint64_t(value);
            value = value >> 64;

            uint32Values.push_back(uint32_t(uint64Value));
            uint64Value = uint64Value >> 32;
            uint32Values.push_back(uint32_t(uint64Value));
        }
    }
}

void QtumDGP::parseDataScheduleContract(std::vector<uint32_t>& uint32Values){
    size_t size = dataTemplate.size() / 32;
    for(size_t i = 0; i < size; i++){
        std::vector<unsigned char> value = std::vector<unsigned char>(dataTemplate.begin() + (i * 32), dataTemplate.begin() + ((i+1) * 32));
        dev::h256 valueTemp(value);
        uint32Values.push_back(uint64_t(dev::u256(valueTemp)));
    }
}

void QtumDGP::parseStorageOneUint32(uint32_t& value){
    dev::h256 blockSizeHash = sha3(dev::h256(dev::u256(0)));
    if(storageTemplate.count(blockSizeHash)){
        value = uint32_t(storageTemplate.find(blockSizeHash)->second.second);
    }
}

void QtumDGP::parseDataOneUint32(uint32_t& value){
    if(dataTemplate.size() == 32){
        value = uint64_t(dev::u256(dev::h256(dataTemplate)));
    }
}

dev::eth::EVMSchedule QtumDGP::createEVMSchedule(){
    dev::eth::EVMSchedule schedule = dev::eth::EIP158Schedule;
    std::vector<uint32_t> uint32Values;

    if(!dgpevm){
        parseStorageScheduleContract(uint32Values);
    } else {
        parseDataScheduleContract(uint32Values);
    }

    if(uint32Values.size() >= 39){
        schedule.tierStepGas = {{uint32Values[0], uint32Values[1], uint32Values[2], uint32Values[3],
                                uint32Values[4], uint32Values[5], uint32Values[6], uint32Values[7]}};
        schedule.expGas = uint32Values[8];
        schedule.expByteGas = uint32Values[9];
        schedule.sha3Gas = uint32Values[10];
        schedule.sha3WordGas = uint32Values[11];
        schedule.sloadGas = uint32Values[12];
        schedule.sstoreSetGas = uint32Values[13];
        schedule.sstoreResetGas = uint32Values[14];
        schedule.sstoreRefundGas = uint32Values[15];
        schedule.jumpdestGas = uint32Values[16];
        schedule.logGas = uint32Values[17];
        schedule.logDataGas = uint32Values[18];
        schedule.logTopicGas = uint32Values[19];
        schedule.createGas = uint32Values[20];
        schedule.callGas = uint32Values[21];
        schedule.callStipend = uint32Values[22];
        schedule.callValueTransferGas = uint32Values[23];
        schedule.callNewAccountGas = uint32Values[24];
        schedule.suicideRefundGas = uint32Values[25];
        schedule.memoryGas = uint32Values[26];
        schedule.quadCoeffDiv = uint32Values[27];
        schedule.createDataGas = uint32Values[28];
        schedule.txGas = uint32Values[29];
        schedule.txCreateGas = uint32Values[30];
        schedule.txDataZeroGas = uint32Values[31];
        schedule.txDataNonZeroGas = uint32Values[32];
        schedule.copyGas = uint32Values[33];
        schedule.extcodesizeGas = uint32Values[34];
        schedule.extcodecopyGas = uint32Values[35];
        schedule.balanceGas = uint32Values[36];
        schedule.suicideGas = uint32Values[37];
        schedule.maxCodeSize = uint32Values[38];
    }
    return schedule;
}

void QtumDGP::clear(){
    templateContract = dev::Address();
    storageDGP.clear();
    storageTemplate.clear();
    paramsInstance.clear();
}
<commit_msg>Make sure callContract() uses new version format<commit_after>#include "qtumDGP.h"

std::vector<ResultExecute> QtumDGP::callContract(const dev::Address& addrContract, std::vector<unsigned char> opcode){
    CBlock block;
    CMutableTransaction tx;
    dev::u256 gasLimit(DEFAULT_BLOCK_GASLIMIT - 1); // MAX_MONEY
    dev::Address senderAddress("ffffffffffffffffffffffffffffffffffffffff");
    tx.vout.push_back(CTxOut(0, CScript() << OP_DUP << OP_HASH160 << senderAddress.asBytes() << OP_EQUALVERIFY << OP_CHECKSIG));
    block.vtx.push_back(MakeTransactionRef(CTransaction(tx)));

    QtumTransaction callTransaction(0, 1, gasLimit, addrContract, opcode, dev::u256(0));
    callTransaction.setVersion(VersionVM::GetEVMDefault());
    callTransaction.forceSender(senderAddress);

    ByteCodeExec exec(block, std::vector<QtumTransaction>(1, callTransaction));
    //if this fails here it can lead to a segfault due to assumptions of this function's result, so just kill with an assert error
    assert(exec.performByteCode(dev::eth::Permanence::Reverted));
    return exec.getResult();
}

dev::eth::EVMSchedule QtumDGP::getGasSchedule(unsigned int blockHeight){
    clear();
    dev::eth::EVMSchedule schedule = dev::eth::EIP158Schedule;
    if(initStorages(GasScheduleDGP, blockHeight, ParseHex("26fadbe2"))){
        schedule = createEVMSchedule();
    }
    return schedule;
}

uint32_t QtumDGP::getUint32FromDGP(unsigned int blockHeight, const dev::Address& contract, std::vector<unsigned char> data){
    uint32_t value = 0;
    if(initStorages(contract, blockHeight, data)){
        if(!dgpevm){
            parseStorageOneUint32(value);
        } else {
            parseDataOneUint32(value);
        }
    }
    return value;
}

uint32_t QtumDGP::getBlockSize(unsigned int blockHeight){
    clear();
    uint32_t result = defaultBlockSizeDGP;
    uint32_t blockSize = getUint32FromDGP(blockHeight, BlockSizeDGP, ParseHex("92ac3c62"));
    if(blockSize <= maxBlockSizeDGP && blockSize >= minBlockSizeDGP){
        result = blockSize;
    }
    return result;
}

uint32_t QtumDGP::getMinGasPrice(unsigned int blockHeight){
    clear();
    uint32_t result = defaultMinGasPriceDGP;
    uint32_t minGasPrice = getUint32FromDGP(blockHeight, GasPriceDGP, ParseHex("3fb58819"));
    if(minGasPrice <= maxMinGasPriceDGP && minGasPrice >= minMinGasPriceDGP){
        result = minGasPrice;
    }
    return result;
}

uint32_t QtumDGP::getBlockGasLimit(unsigned int blockHeight){
    clear();
    uint32_t result = defaultBlockGasLimitDGP;
    uint32_t blockGasLimit = getUint32FromDGP(blockHeight, BlockGasLimitDGP, ParseHex("2cc8377d"));
    if(blockGasLimit <= maxBlockGasLimitDGP && blockGasLimit >= minBlockGasLimitDGP){
        result = blockGasLimit;
    }
    return result;
}

bool QtumDGP::initStorages(const dev::Address& addr, unsigned int blockHeight, std::vector<unsigned char> data){
    initStorageDGP(addr);
    createParamsInstance();
    dev::Address address = getAddressForBlock(blockHeight);
    if(address != dev::Address()){
        if(!dgpevm){
            initStorageTemplate(address);
        } else {
            initDataTemplate(address, data);
        }
        return true;
    }
    return false;
}

void QtumDGP::initStorageDGP(const dev::Address& addr){
    storageDGP = state->storage(addr);
}

void QtumDGP::initStorageTemplate(const dev::Address& addr){
    storageTemplate = state->storage(addr);
}

void QtumDGP::initDataTemplate(const dev::Address& addr, std::vector<unsigned char>& data){
    dataTemplate = callContract(addr, data)[0].execRes.output;
}

void QtumDGP::createParamsInstance(){
    dev::h256 paramsInstanceHash = sha3(dev::h256("0000000000000000000000000000000000000000000000000000000000000000"));
    if(storageDGP.count(paramsInstanceHash)){
        dev::u256 paramsInstanceSize = storageDGP.find(paramsInstanceHash)->second.second;
        for(size_t i = 0; i < size_t(paramsInstanceSize); i++){
            std::pair<unsigned int, dev::Address> params;
            params.first = uint64_t(storageDGP.find(sha3(paramsInstanceHash))->second.second);
            ++paramsInstanceHash;
            params.second = dev::right160(dev::h256(storageDGP.find(sha3(paramsInstanceHash))->second.second));
            ++paramsInstanceHash;
            paramsInstance.push_back(params);
        }
    }
}

dev::Address QtumDGP::getAddressForBlock(unsigned int blockHeight){
    for(auto i = paramsInstance.rbegin(); i != paramsInstance.rend(); i++){
        if(i->first <= blockHeight)
            return i->second;
    }
    return dev::Address();
}

void QtumDGP::parseStorageScheduleContract(std::vector<uint32_t>& uint32Values){
    std::vector<std::pair<dev::u256, dev::u256>> data;
    for(size_t i = 0; i < 5; i++){
        dev::h256 gasScheduleHash = sha3(dev::h256(dev::u256(i)));
        if(storageTemplate.count(gasScheduleHash)){
            dev::u256 key = storageTemplate.find(gasScheduleHash)->second.first;
            dev::u256 value = storageTemplate.find(gasScheduleHash)->second.second;
            data.push_back(std::make_pair(key, value));
        }
    }

    std::sort(data.begin(), data.end(), [&data](std::pair<dev::u256, dev::u256>& a, std::pair<dev::u256, dev::u256>& b){
        return a.first < b.first;
    });

    for(std::pair<dev::u256, dev::u256> d : data){
        dev::u256 value = d.second;
        for(size_t i = 0; i < 4; i++){
            uint64_t uint64Value = uint64_t(value);
            value = value >> 64;

            uint32Values.push_back(uint32_t(uint64Value));
            uint64Value = uint64Value >> 32;
            uint32Values.push_back(uint32_t(uint64Value));
        }
    }
}

void QtumDGP::parseDataScheduleContract(std::vector<uint32_t>& uint32Values){
    size_t size = dataTemplate.size() / 32;
    for(size_t i = 0; i < size; i++){
        std::vector<unsigned char> value = std::vector<unsigned char>(dataTemplate.begin() + (i * 32), dataTemplate.begin() + ((i+1) * 32));
        dev::h256 valueTemp(value);
        uint32Values.push_back(uint64_t(dev::u256(valueTemp)));
    }
}

void QtumDGP::parseStorageOneUint32(uint32_t& value){
    dev::h256 blockSizeHash = sha3(dev::h256(dev::u256(0)));
    if(storageTemplate.count(blockSizeHash)){
        value = uint32_t(storageTemplate.find(blockSizeHash)->second.second);
    }
}

void QtumDGP::parseDataOneUint32(uint32_t& value){
    if(dataTemplate.size() == 32){
        value = uint64_t(dev::u256(dev::h256(dataTemplate)));
    }
}

dev::eth::EVMSchedule QtumDGP::createEVMSchedule(){
    dev::eth::EVMSchedule schedule = dev::eth::EIP158Schedule;
    std::vector<uint32_t> uint32Values;

    if(!dgpevm){
        parseStorageScheduleContract(uint32Values);
    } else {
        parseDataScheduleContract(uint32Values);
    }

    if(uint32Values.size() >= 39){
        schedule.tierStepGas = {{uint32Values[0], uint32Values[1], uint32Values[2], uint32Values[3],
                                uint32Values[4], uint32Values[5], uint32Values[6], uint32Values[7]}};
        schedule.expGas = uint32Values[8];
        schedule.expByteGas = uint32Values[9];
        schedule.sha3Gas = uint32Values[10];
        schedule.sha3WordGas = uint32Values[11];
        schedule.sloadGas = uint32Values[12];
        schedule.sstoreSetGas = uint32Values[13];
        schedule.sstoreResetGas = uint32Values[14];
        schedule.sstoreRefundGas = uint32Values[15];
        schedule.jumpdestGas = uint32Values[16];
        schedule.logGas = uint32Values[17];
        schedule.logDataGas = uint32Values[18];
        schedule.logTopicGas = uint32Values[19];
        schedule.createGas = uint32Values[20];
        schedule.callGas = uint32Values[21];
        schedule.callStipend = uint32Values[22];
        schedule.callValueTransferGas = uint32Values[23];
        schedule.callNewAccountGas = uint32Values[24];
        schedule.suicideRefundGas = uint32Values[25];
        schedule.memoryGas = uint32Values[26];
        schedule.quadCoeffDiv = uint32Values[27];
        schedule.createDataGas = uint32Values[28];
        schedule.txGas = uint32Values[29];
        schedule.txCreateGas = uint32Values[30];
        schedule.txDataZeroGas = uint32Values[31];
        schedule.txDataNonZeroGas = uint32Values[32];
        schedule.copyGas = uint32Values[33];
        schedule.extcodesizeGas = uint32Values[34];
        schedule.extcodecopyGas = uint32Values[35];
        schedule.balanceGas = uint32Values[36];
        schedule.suicideGas = uint32Values[37];
        schedule.maxCodeSize = uint32Values[38];
    }
    return schedule;
}

void QtumDGP::clear(){
    templateContract = dev::Address();
    storageDGP.clear();
    storageTemplate.clear();
    paramsInstance.clear();
}
<|endoftext|>


<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (C) 2019, James R. Barlow (https://github.com/jbarlow83/)
 */

#include <sstream>
#include <type_traits>
#include <cerrno>
#include <cstring>
#include <cstdio>

#include "pikepdf.h"

#include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFSystemError.hh>
#include <qpdf/QUtil.hh>

#include <pybind11/stl.h>
#include <pybind11/iostream.h>
#include <pybind11/buffer_info.h>

#include "qpdf_pagelist.h"
#include "utils.h"

uint DECIMAL_PRECISION = 15;

class TemporaryErrnoChange {
public:
    TemporaryErrnoChange(int val) {
        stored = errno;
        errno = val;
    }
    ~TemporaryErrnoChange() {
        errno = stored;
    }
private:
    int stored;
};

PYBIND11_MODULE(_qpdf, m) {
    //py::options options;
    //options.disable_function_signatures();

    m.doc() = "pikepdf provides a Pythonic interface for QPDF";

    m.def("qpdf_version", &QPDF::QPDFVersion, "Get libqpdf version");

    init_qpdf(m);
    init_pagelist(m);
    init_object(m);
    init_annotation(m);
    init_page(m);

    m.def("utf8_to_pdf_doc",
        [](py::str utf8, char unknown) {
            std::string pdfdoc;
            bool success = QUtil::utf8_to_pdf_doc(std::string(utf8), pdfdoc, unknown);
            return py::make_tuple(success, py::bytes(pdfdoc));
        }
    );
    m.def("pdf_doc_to_utf8",
        [](py::bytes pdfdoc) -> py::str {
            return py::str(QUtil::pdf_doc_to_utf8(pdfdoc));
        }
    );

    m.def("_test_file_not_found",
        []() -> void {
            auto file = QUtil::safe_fopen("does_not_exist__42", "rb");
            if (file)
                fclose(file);
        },
        "Used to test that C++ system error -> Python exception propagation works."
    );

    m.def("set_decimal_precision",
        [](uint prec) {
            DECIMAL_PRECISION = prec;
            return DECIMAL_PRECISION;
        },
        "Set the number of decimal digits to use when converting floats."
    );
    m.def("get_decimal_precision",
        []() {
            return DECIMAL_PRECISION;
        },
        "Get the number of decimal digits to use when converting floats."
    );

    static py::exception<QPDFExc> exc_main(m, "PdfError");
    static py::exception<QPDFExc> exc_password(m, "PasswordError");
    py::register_exception_translator([](std::exception_ptr p) {
        try {
            if (p) std::rethrow_exception(p);
        } catch (const QPDFExc &e) {
            if (e.getErrorCode() == qpdf_e_password) {
                exc_password(e.what());
            } else {
                exc_main(e.what());
            }
        } catch (const QPDFSystemError &e) {
            if (e.getErrno() != 0) {
                TemporaryErrnoChange errno_holder(e.getErrno());
                PyErr_SetFromErrnoWithFilename(PyExc_OSError, e.getDescription().c_str());
            } else {
                exc_main(e.what());
            }
        }
    });

#ifdef VERSION_INFO
    m.attr("__version__") = VERSION_INFO;
#else
    m.attr("__version__") = "dev";
#endif
}
<commit_msg>MSVC handles command line defines differently<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (C) 2019, James R. Barlow (https://github.com/jbarlow83/)
 */

#include <sstream>
#include <type_traits>
#include <cerrno>
#include <cstring>
#include <cstdio>

#include "pikepdf.h"

#include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFSystemError.hh>
#include <qpdf/QUtil.hh>

#include <pybind11/stl.h>
#include <pybind11/iostream.h>
#include <pybind11/buffer_info.h>

#include "qpdf_pagelist.h"
#include "utils.h"

uint DECIMAL_PRECISION = 15;

class TemporaryErrnoChange {
public:
    TemporaryErrnoChange(int val) {
        stored = errno;
        errno = val;
    }
    ~TemporaryErrnoChange() {
        errno = stored;
    }
private:
    int stored;
};

PYBIND11_MODULE(_qpdf, m) {
    //py::options options;
    //options.disable_function_signatures();

    m.doc() = "pikepdf provides a Pythonic interface for QPDF";

    m.def("qpdf_version", &QPDF::QPDFVersion, "Get libqpdf version");

    init_qpdf(m);
    init_pagelist(m);
    init_object(m);
    init_annotation(m);
    init_page(m);

    m.def("utf8_to_pdf_doc",
        [](py::str utf8, char unknown) {
            std::string pdfdoc;
            bool success = QUtil::utf8_to_pdf_doc(std::string(utf8), pdfdoc, unknown);
            return py::make_tuple(success, py::bytes(pdfdoc));
        }
    );
    m.def("pdf_doc_to_utf8",
        [](py::bytes pdfdoc) -> py::str {
            return py::str(QUtil::pdf_doc_to_utf8(pdfdoc));
        }
    );

    m.def("_test_file_not_found",
        []() -> void {
            auto file = QUtil::safe_fopen("does_not_exist__42", "rb");
            if (file)
                fclose(file);
        },
        "Used to test that C++ system error -> Python exception propagation works."
    );

    m.def("set_decimal_precision",
        [](uint prec) {
            DECIMAL_PRECISION = prec;
            return DECIMAL_PRECISION;
        },
        "Set the number of decimal digits to use when converting floats."
    );
    m.def("get_decimal_precision",
        []() {
            return DECIMAL_PRECISION;
        },
        "Get the number of decimal digits to use when converting floats."
    );

    static py::exception<QPDFExc> exc_main(m, "PdfError");
    static py::exception<QPDFExc> exc_password(m, "PasswordError");
    py::register_exception_translator([](std::exception_ptr p) {
        try {
            if (p) std::rethrow_exception(p);
        } catch (const QPDFExc &e) {
            if (e.getErrorCode() == qpdf_e_password) {
                exc_password(e.what());
            } else {
                exc_main(e.what());
            }
        } catch (const QPDFSystemError &e) {
            if (e.getErrno() != 0) {
                TemporaryErrnoChange errno_holder(e.getErrno());
                PyErr_SetFromErrnoWithFilename(PyExc_OSError, e.getDescription().c_str());
            } else {
                exc_main(e.what());
            }
        }
    });

#if defined(VERSION_INFO) && defined(_MSC_VER)
#define msvc_inner_stringify(s) #s
#define msvc_stringify(s) msvc_inner_stringify(s)
    m.attr("__version__") = msvc_stringify(VERSION_INFO);
#undef msvc_stringify
#undef msvc_inner_stringify
#elif defined(VERSION_INFO)
    m.attr("__version__") = VERSION_INFO;
#else
    m.attr("__version__") = "dev";
#endif
}
<|endoftext|>