<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsgdefaultglyphnode_p_p.h"

#include <qopenglshaderprogram.h>

#include <QtGui/private/qtextureglyphcache_gl_p.h>
#include <private/qfontengine_p.h>
#include <private/qopenglextensions_p.h>

#include <private/qsgtexture_p.h>

#include <private/qrawfont_p.h>

QT_BEGIN_NAMESPACE

class QSGTextMaskMaterialData : public QSGMaterialShader
{
public:
    QSGTextMaskMaterialData();

    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
    virtual char const *const *attributeNames() const;
private:
    virtual void initialize();
    virtual const char *vertexShader() const;
    virtual const char *fragmentShader() const;

    int m_matrix_id;
    int m_color_id;
    int m_textureScale_id;
};

const char *QSGTextMaskMaterialData::vertexShader() const {
    return
        "uniform highp mat4 matrix;                     \n"
        "uniform highp vec2 textureScale;               \n"
        "attribute highp vec4 vCoord;                   \n"
        "attribute highp vec2 tCoord;                   \n"
        "varying highp vec2 sampleCoord;                \n"
        "void main() {                                  \n"
        "     sampleCoord = tCoord * textureScale;      \n"
        "     gl_Position = matrix * vCoord;            \n"
        "}";
}

const char *QSGTextMaskMaterialData::fragmentShader() const {
    return
        "varying highp vec2 sampleCoord;                \n"
        "uniform sampler2D texture;                     \n"
        "uniform lowp vec4 color;                       \n"
        "void main() {                                  \n"
        "    gl_FragColor = color * texture2D(texture, sampleCoord).a; \n"
        "}";
}

char const *const *QSGTextMaskMaterialData::attributeNames() const
{
    static char const *const attr[] = { "vCoord", "tCoord", 0 };
    return attr;
}

QSGTextMaskMaterialData::QSGTextMaskMaterialData()
{
}

void QSGTextMaskMaterialData::initialize()
{
    m_matrix_id = program()->uniformLocation("matrix");
    m_color_id = program()->uniformLocation("color");
    m_textureScale_id = program()->uniformLocation("textureScale");
}

void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
    Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
    QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
    QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);

    if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
        QVector4D color(material->color().redF(), material->color().greenF(),
                        material->color().blueF(), material->color().alphaF());
        color *= state.opacity();
        program()->setUniformValue(m_color_id, color);
    }

    bool updated = material->ensureUpToDate();
    Q_ASSERT(material->texture());

    Q_ASSERT(oldMaterial == 0 || oldMaterial->texture());
    if (updated
            || oldMaterial == 0
            || oldMaterial->texture()->textureId() != material->texture()->textureId()) {
        program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
                                                               1.0 / material->cacheTextureHeight()));
        glBindTexture(GL_TEXTURE_2D, material->texture()->textureId());

        // Set the mag/min filters to be linear. We only need to do this when the texture
        // has been recreated.
        if (updated) {
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        }
    }

    if (state.isMatrixDirty())
        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
}

QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font)
    : m_texture(0), m_glyphCache(), m_font(font)
{
    init();
}

QSGTextMaskMaterial::~QSGTextMaskMaterial()
{
}

void QSGTextMaskMaterial::init()
{
    Q_ASSERT(m_font.isValid());

    QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_A8;
    setFlag(Blending, true);

    QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
    Q_ASSERT(ctx != 0);

    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    if (fontD->fontEngine != 0) {
        m_glyphCache = fontD->fontEngine->glyphCache(ctx, type, QTransform());
        if (!m_glyphCache || m_glyphCache->cacheType() != type) {
            m_glyphCache = new QOpenGLTextureGlyphCache(type, QTransform());
            fontD->fontEngine->setGlyphCache(ctx, m_glyphCache.data());
        }
    }
}

void QSGTextMaskMaterial::populate(const QPointF &p,
                                const QVector<quint32> &glyphIndexes,
                                const QVector<QPointF> &glyphPositions,
                                QSGGeometry *geometry,
                                QRectF *boundingRect,
                                QPointF *baseLine)
{
    Q_ASSERT(m_font.isValid());
    QVector<QFixedPoint> fixedPointPositions;
    for (int i=0; i<glyphPositions.size(); ++i)
        fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));

    QTextureGlyphCache *cache = glyphCache();

    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(),
                    fixedPointPositions.data());
    cache->fillInPendingGlyphs();

    int margin = cache->glyphMargin();

    Q_ASSERT(geometry->indexType() == GL_UNSIGNED_SHORT);
    geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6);
    QVector4D *vp = (QVector4D *)geometry->vertexDataAsTexturedPoint2D();
    Q_ASSERT(geometry->stride() == sizeof(QVector4D));
    ushort *ip = geometry->indexDataAsUShort();

    QPointF position(p.x(), p.y() - m_font.ascent());
    bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
    for (int i=0; i<glyphIndexes.size(); ++i) {
         QFixed subPixelPosition;
         if (supportsSubPixelPositions)
             subPixelPosition = cache->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));

         QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
         const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);

         QPointF glyphPosition = glyphPositions.at(i) + position;
         int x = qRound(glyphPosition.x()) + c.baseLineX - margin;
         int y = qRound(glyphPosition.y()) - c.baseLineY - margin;

         *boundingRect |= QRectF(x + margin, y + margin, c.w, c.h);

         float cx1 = x;
         float cx2 = x + c.w;
         float cy1 = y;
         float cy2 = y + c.h;

         float tx1 = c.x;
         float tx2 = (c.x + c.w);
         float ty1 = c.y;
         float ty2 = (c.y + c.h);

         if (baseLine->isNull())
             *baseLine = glyphPosition;

         vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1);
         vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1);
         vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2);
         vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2);

         int o = i * 4;
         ip[6 * i + 0] = o + 0;
         ip[6 * i + 1] = o + 2;
         ip[6 * i + 2] = o + 3;
         ip[6 * i + 3] = o + 3;
         ip[6 * i + 4] = o + 1;
         ip[6 * i + 5] = o + 0;
    }
}

QSGMaterialType *QSGTextMaskMaterial::type() const
{
    static QSGMaterialType type;
    return &type;
}

QOpenGLTextureGlyphCache *QSGTextMaskMaterial::glyphCache() const
{
    return static_cast<QOpenGLTextureGlyphCache*>(m_glyphCache.data());
}

QSGMaterialShader *QSGTextMaskMaterial::createShader() const
{
    return new QSGTextMaskMaterialData;
}

int QSGTextMaskMaterial::compare(const QSGMaterial *o) const
{
    Q_ASSERT(o && type() == o->type());
    const QSGTextMaskMaterial *other = static_cast<const QSGTextMaskMaterial *>(o);
    if (m_glyphCache != other->m_glyphCache)
        return m_glyphCache - other->m_glyphCache;
    QRgb c1 = m_color.rgba();
    QRgb c2 = other->m_color.rgba();
    return int(c2 < c1) - int(c1 < c2);
}

bool QSGTextMaskMaterial::ensureUpToDate()
{
    QSize glyphCacheSize(glyphCache()->width(), glyphCache()->height());
    if (glyphCacheSize != m_size) {
        if (m_texture)
            delete m_texture;
        m_texture = new QSGPlainTexture();
        m_texture->setTextureId(glyphCache()->texture());
        m_texture->setTextureSize(QSize(glyphCache()->width(), glyphCache()->height()));
        m_texture->setOwnsTexture(false);

        m_size = glyphCacheSize;

        return true;
    } else {
        return false;
    }
}

int QSGTextMaskMaterial::cacheTextureWidth() const
{
    return glyphCache()->width();
}

int QSGTextMaskMaterial::cacheTextureHeight() const
{
    return glyphCache()->height();
}

QT_END_NAMESPACE
<commit_msg>Compile, qtextureglyphcache_gl_p.h -> qopengltextureglyphcache_p.h<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsgdefaultglyphnode_p_p.h"

#include <qopenglshaderprogram.h>

#include <QtGui/private/qopengltextureglyphcache_p.h>
#include <private/qfontengine_p.h>
#include <private/qopenglextensions_p.h>

#include <private/qsgtexture_p.h>

#include <private/qrawfont_p.h>

QT_BEGIN_NAMESPACE

class QSGTextMaskMaterialData : public QSGMaterialShader
{
public:
    QSGTextMaskMaterialData();

    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
    virtual char const *const *attributeNames() const;
private:
    virtual void initialize();
    virtual const char *vertexShader() const;
    virtual const char *fragmentShader() const;

    int m_matrix_id;
    int m_color_id;
    int m_textureScale_id;
};

const char *QSGTextMaskMaterialData::vertexShader() const {
    return
        "uniform highp mat4 matrix;                     \n"
        "uniform highp vec2 textureScale;               \n"
        "attribute highp vec4 vCoord;                   \n"
        "attribute highp vec2 tCoord;                   \n"
        "varying highp vec2 sampleCoord;                \n"
        "void main() {                                  \n"
        "     sampleCoord = tCoord * textureScale;      \n"
        "     gl_Position = matrix * vCoord;            \n"
        "}";
}

const char *QSGTextMaskMaterialData::fragmentShader() const {
    return
        "varying highp vec2 sampleCoord;                \n"
        "uniform sampler2D texture;                     \n"
        "uniform lowp vec4 color;                       \n"
        "void main() {                                  \n"
        "    gl_FragColor = color * texture2D(texture, sampleCoord).a; \n"
        "}";
}

char const *const *QSGTextMaskMaterialData::attributeNames() const
{
    static char const *const attr[] = { "vCoord", "tCoord", 0 };
    return attr;
}

QSGTextMaskMaterialData::QSGTextMaskMaterialData()
{
}

void QSGTextMaskMaterialData::initialize()
{
    m_matrix_id = program()->uniformLocation("matrix");
    m_color_id = program()->uniformLocation("color");
    m_textureScale_id = program()->uniformLocation("textureScale");
}

void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
    Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
    QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
    QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);

    if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
        QVector4D color(material->color().redF(), material->color().greenF(),
                        material->color().blueF(), material->color().alphaF());
        color *= state.opacity();
        program()->setUniformValue(m_color_id, color);
    }

    bool updated = material->ensureUpToDate();
    Q_ASSERT(material->texture());

    Q_ASSERT(oldMaterial == 0 || oldMaterial->texture());
    if (updated
            || oldMaterial == 0
            || oldMaterial->texture()->textureId() != material->texture()->textureId()) {
        program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(),
                                                               1.0 / material->cacheTextureHeight()));
        glBindTexture(GL_TEXTURE_2D, material->texture()->textureId());

        // Set the mag/min filters to be linear. We only need to do this when the texture
        // has been recreated.
        if (updated) {
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        }
    }

    if (state.isMatrixDirty())
        program()->setUniformValue(m_matrix_id, state.combinedMatrix());
}

QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font)
    : m_texture(0), m_glyphCache(), m_font(font)
{
    init();
}

QSGTextMaskMaterial::~QSGTextMaskMaterial()
{
}

void QSGTextMaskMaterial::init()
{
    Q_ASSERT(m_font.isValid());

    QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_A8;
    setFlag(Blending, true);

    QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
    Q_ASSERT(ctx != 0);

    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    if (fontD->fontEngine != 0) {
        m_glyphCache = fontD->fontEngine->glyphCache(ctx, type, QTransform());
        if (!m_glyphCache || m_glyphCache->cacheType() != type) {
            m_glyphCache = new QOpenGLTextureGlyphCache(type, QTransform());
            fontD->fontEngine->setGlyphCache(ctx, m_glyphCache.data());
        }
    }
}

void QSGTextMaskMaterial::populate(const QPointF &p,
                                const QVector<quint32> &glyphIndexes,
                                const QVector<QPointF> &glyphPositions,
                                QSGGeometry *geometry,
                                QRectF *boundingRect,
                                QPointF *baseLine)
{
    Q_ASSERT(m_font.isValid());
    QVector<QFixedPoint> fixedPointPositions;
    for (int i=0; i<glyphPositions.size(); ++i)
        fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));

    QTextureGlyphCache *cache = glyphCache();

    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(),
                    fixedPointPositions.data());
    cache->fillInPendingGlyphs();

    int margin = cache->glyphMargin();

    Q_ASSERT(geometry->indexType() == GL_UNSIGNED_SHORT);
    geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6);
    QVector4D *vp = (QVector4D *)geometry->vertexDataAsTexturedPoint2D();
    Q_ASSERT(geometry->stride() == sizeof(QVector4D));
    ushort *ip = geometry->indexDataAsUShort();

    QPointF position(p.x(), p.y() - m_font.ascent());
    bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
    for (int i=0; i<glyphIndexes.size(); ++i) {
         QFixed subPixelPosition;
         if (supportsSubPixelPositions)
             subPixelPosition = cache->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));

         QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
         const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);

         QPointF glyphPosition = glyphPositions.at(i) + position;
         int x = qRound(glyphPosition.x()) + c.baseLineX - margin;
         int y = qRound(glyphPosition.y()) - c.baseLineY - margin;

         *boundingRect |= QRectF(x + margin, y + margin, c.w, c.h);

         float cx1 = x;
         float cx2 = x + c.w;
         float cy1 = y;
         float cy2 = y + c.h;

         float tx1 = c.x;
         float tx2 = (c.x + c.w);
         float ty1 = c.y;
         float ty2 = (c.y + c.h);

         if (baseLine->isNull())
             *baseLine = glyphPosition;

         vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1);
         vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1);
         vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2);
         vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2);

         int o = i * 4;
         ip[6 * i + 0] = o + 0;
         ip[6 * i + 1] = o + 2;
         ip[6 * i + 2] = o + 3;
         ip[6 * i + 3] = o + 3;
         ip[6 * i + 4] = o + 1;
         ip[6 * i + 5] = o + 0;
    }
}

QSGMaterialType *QSGTextMaskMaterial::type() const
{
    static QSGMaterialType type;
    return &type;
}

QOpenGLTextureGlyphCache *QSGTextMaskMaterial::glyphCache() const
{
    return static_cast<QOpenGLTextureGlyphCache*>(m_glyphCache.data());
}

QSGMaterialShader *QSGTextMaskMaterial::createShader() const
{
    return new QSGTextMaskMaterialData;
}

int QSGTextMaskMaterial::compare(const QSGMaterial *o) const
{
    Q_ASSERT(o && type() == o->type());
    const QSGTextMaskMaterial *other = static_cast<const QSGTextMaskMaterial *>(o);
    if (m_glyphCache != other->m_glyphCache)
        return m_glyphCache - other->m_glyphCache;
    QRgb c1 = m_color.rgba();
    QRgb c2 = other->m_color.rgba();
    return int(c2 < c1) - int(c1 < c2);
}

bool QSGTextMaskMaterial::ensureUpToDate()
{
    QSize glyphCacheSize(glyphCache()->width(), glyphCache()->height());
    if (glyphCacheSize != m_size) {
        if (m_texture)
            delete m_texture;
        m_texture = new QSGPlainTexture();
        m_texture->setTextureId(glyphCache()->texture());
        m_texture->setTextureSize(QSize(glyphCache()->width(), glyphCache()->height()));
        m_texture->setOwnsTexture(false);

        m_size = glyphCacheSize;

        return true;
    } else {
        return false;
    }
}

int QSGTextMaskMaterial::cacheTextureWidth() const
{
    return glyphCache()->width();
}

int QSGTextMaskMaterial::cacheTextureHeight() const
{
    return glyphCache()->height();
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>/* dtkComposerNodeLoopDataComposite.cpp ---
 *
 * Author: Thibaud Kloczko
 * Copyright (C) 2011 - Thibaud Kloczko, Inria.
 * Created: Wed Oct 12 16:02:18 2011 (+0200)
 * Version: $Id$
 * Last-Updated: Fri Oct 14 16:27:22 2011 (+0200)
 *           By: Julien Wintz
 *     Update #: 140
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkComposerNodeLoopDataComposite.h"

#include <dtkComposer/dtkComposerEdge>
#include <dtkComposer/dtkComposerNode>
#include <dtkComposer/dtkComposerNodeControlBlock>
#include <dtkComposer/dtkComposerNodeNumber>
#include <dtkComposer/dtkComposerNodeProperty>

#include <dtkCore/dtkAbstractData>
#include <dtkCore/dtkAbstractDataComposite>
#include <dtkCore/dtkAbstractProcess>
#include <dtkCore/dtkGlobal>
#include <dtkCore/dtkLog>

#define DTK_DEBUG_COMPOSER_INTERACTION 1
#define DTK_DEBUG_COMPOSER_EVALUATION 1

// /////////////////////////////////////////////////////////////////
// dtkComposerNodeLoopDataCompositePrivate declaration
// /////////////////////////////////////////////////////////////////

class dtkComposerNodeLoopDataCompositePrivate
{
public:
    dtkComposerNodeControlBlock *block_loop;

public:
    dtkxarch_int from_default;
    dtkxarch_int to_default;
    dtkxarch_int step_default;

    dtkxarch_int from;
    dtkxarch_int to;
    dtkxarch_int step;
    dtkxarch_int index;

    dtkAbstractData *item;

    dtkAbstractDataComposite *composite;

    bool valid_input_composite;
};

// /////////////////////////////////////////////////////////////////
// dtkComposerNodeLoopDataComposite implementation
// /////////////////////////////////////////////////////////////////

dtkComposerNodeLoopDataComposite::dtkComposerNodeLoopDataComposite(dtkComposerNode *parent) : dtkComposerNodeLoop(parent), d(new dtkComposerNodeLoopDataCompositePrivate)
{
    d->block_loop = this->addBlock("loop");
    d->block_loop->setInteractive(false);
    d->block_loop->setHeightRatio(1);
    this->addInputProperty(d->block_loop->addInputProperty("from", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("to", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("step", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("item", dtkComposerNodeProperty::Output, dtkComposerNodeProperty::Multiple, dtkComposerNodeProperty::AsLoopInput, this));

    this->setColor(QColor("#2ABFFF"));
    this->setInputPropertyName("composite");
    this->setTitle("Composite Data Loop");
    this->setType("dtkComposerLoopDataComposite");

    d->from_default = 0;
    d->to_default = 0;
    d->step_default = 1;

    d->from = -1;
    d->to = -1;
    d->step = -1;

    d->index = 0;

    d->item = NULL;
    d->composite = NULL;

    d->valid_input_composite = false;
}

dtkComposerNodeLoopDataComposite::~dtkComposerNodeLoopDataComposite(void)
{
    delete d;

    d = NULL;
}

void dtkComposerNodeLoopDataComposite::layout(void)
{
    dtkComposerNodeControl::layout();

    QRectF  node_rect = this->boundingRect();
    qreal node_radius = this->nodeRadius();

    int j;
    qreal offset = 23;

    dtkComposerNodeControlBlock *block = this->blocks().at(0);

    block->setRect(QRectF(node_rect.x(),
                          node_rect.y() + offset,
                          node_rect.width(),
                          block->height()));

    j = 0;
    foreach(dtkComposerNodeProperty *property, block->inputProperties()) {

        property->setRect(QRectF(block->mapRectToParent(block->rect()).left() + node_radius,
                                 block->mapRectToParent(block->rect()).top()  + node_radius * (4*j + 1),
                                 2 * node_radius,
                                 2 * node_radius ));

        if (property->name() == "item") {
            property->mirror();
            j++;
        }

        j++;
    }
    j = 5;
    foreach(dtkComposerNodeProperty *property, block->outputProperties()) {

        property->setRect(QRectF(block->mapRectToParent(block->rect()).right() - node_radius * 3,
                                 block->mapRectToParent(block->rect()).top()   + node_radius * (4*j + 1),
                                 2 * node_radius,
                                 2 * node_radius ));

        j++;
    }
}

void dtkComposerNodeLoopDataComposite::update(void)
{

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
    qDebug() << DTK_PRETTY_FUNCTION << this;
#endif

    if (this->isRunning()) {

        return;

    } else {

        if (!this->dirty())
            return;

        // -- Check dirty input value

        if (this->dirtyInputValue())
            return;

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_GREEN << DTK_PRETTY_FUNCTION << "Dirty input value OK" << DTK_NO_COLOR;
#endif

        // -- Check dirty inputs

        if (this->dtkComposerNode::dirtyUpstreamNodes())
            return;

        // -- Mark dirty outputs

        this->dtkComposerNode::markDirtyDownstreamNodes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_GREEN << DTK_PRETTY_FUNCTION << "All output nodes are set to dirty" << DTK_NO_COLOR;
#endif

        // -- Clean active input routes

        this->cleanInputActiveRoutes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Input active routes cleaned" << DTK_NO_COLOR;
#endif

        // -- Pull

        foreach(dtkComposerEdge *i_route, this->inputRoutes())
            this->pull(i_route, i_route->destination());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Pull done" << DTK_NO_COLOR;
#endif

        // -- Set input composite and loop options

        foreach(dtkComposerEdge *i_route, this->inputActiveRoutes()) {
            if (i_route->destination() == this->inputProperty()) {

                dtkAbstractData *data = NULL;

                if(dtkAbstractData *dt = qobject_cast<dtkAbstractData *>(i_route->source()->node()->object())) {

                    data = dt;

                } else if(dtkAbstractProcess *process = qobject_cast<dtkAbstractProcess *>(i_route->source()->node()->object())) {

                    if(i_route->source()->node()->outputProperties().count() >= 1)
                        data = process->output(i_route->source()->node()->number(i_route->source()));
                    else
                        data = process->output();

                }

                if (data) {

                    d->composite = qobject_cast<dtkAbstractDataComposite *>(data);
                    if (!d->composite) {
                        dtkDebug() << DTK_PRETTY_FUNCTION << "input data is not of dtkAbstractDataComposite* type.";
                        return;
                    }
                    if (d->composite->count())
                        this->setObject((*d->composite)[0]);

                    d->to_default = d->composite->count()-1;

                    d->valid_input_composite = true;

                } else {

                    dtkDebug() << DTK_PRETTY_FUNCTION << "input data is not defined";
                    return;

                }

            } else if (i_route->destination()->name() == "from") {

                d->from = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "from value =" << d->from << DTK_NO_COLOR;
#endif

            } else if (i_route->destination()->name() == "to") {

                d->to = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "to value =" << d->to << DTK_NO_COLOR;
#endif

            } else if (i_route->destination()->name() == "step") {

                d->step = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());
#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "step value =" << d->step << DTK_NO_COLOR;
#endif

            }

            qDebug() << i_route;

        }

        if (!d->valid_input_composite) {
            dtkDebug() << DTK_PRETTY_FUNCTION << " input composite property is not connected.";
            return;
        }

        if ((d->from > d->to) && (d->from > d->to_default))
            d->from = d->to_default;
        else if (d->from < 0)
            d->from = d->from_default;
        else if (d->to < d->from && d->to < 0)
            d->to = d->from_default;
        else if (d->to > d->to_default)
            d->to = d->to_default;

        if (d->step < 0 && (d->from < d->to))
            d->step = d->step_default;

        d->index = d->from;

        // -- Running logics of conditional block

        this->setRunning(true);

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_RED  << "Loop initialization done" << DTK_NO_COLOR;
#endif

        while(d->index <= d->to) {

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
            qDebug() << DTK_COLOR_BG_RED  << "Loop is running, index = " << d->index << DTK_NO_COLOR;
#endif

            d->item = (*d->composite)[d->index];
            this->run();
            this->updatePassThroughVariables();
            d->index += d->step;

        }

        // -- Clean active output routes

        this->cleanOutputActiveRoutes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Output active routes cleaned" << DTK_NO_COLOR;
#endif

        // -- Push

        foreach(dtkComposerEdge *o_route, this->outputRoutes())
            this->push(o_route, o_route->source());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Push done" << DTK_NO_COLOR;
#endif

        // -- Forward

        this->setDirty(false);
        this->setRunning(false);

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_BLUE << DTK_PRETTY_FUNCTION << "Forward done" << DTK_NO_COLOR;
#endif

        foreach(dtkComposerEdge *o_route, this->outputRoutes())
            o_route->destination()->node()->update();
    }
}

void dtkComposerNodeLoopDataComposite::onEdgeConnected(dtkComposerEdge *edge)
{
    if(true)
        edge->invalidate();
    else
        ; // dtkComposerNodeLoop::onEdgeConnected(edge);
}

void dtkComposerNodeLoopDataComposite::pull(dtkComposerEdge *i_route, dtkComposerNodeProperty *property)
{
    if (property->name() == "from" || property->name() == "to" || property->name() == "step")
        this->addInputActiveRoute(i_route);

    dtkComposerNodeLoop::pull(i_route, property);
}

QVariant dtkComposerNodeLoopDataComposite::value(dtkComposerNodeProperty *property)
{
    return QVariant();
}
<commit_msg>As property type checking is not yet implemented, composite node data loop will invalidate the edge but build the routes anyway.<commit_after>/* dtkComposerNodeLoopDataComposite.cpp ---
 *
 * Author: Thibaud Kloczko
 * Copyright (C) 2011 - Thibaud Kloczko, Inria.
 * Created: Wed Oct 12 16:02:18 2011 (+0200)
 * Version: $Id$
 * Last-Updated: Fri Oct 14 16:28:35 2011 (+0200)
 *           By: Julien Wintz
 *     Update #: 143
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkComposerNodeLoopDataComposite.h"

#include <dtkComposer/dtkComposerEdge>
#include <dtkComposer/dtkComposerNode>
#include <dtkComposer/dtkComposerNodeControlBlock>
#include <dtkComposer/dtkComposerNodeNumber>
#include <dtkComposer/dtkComposerNodeProperty>

#include <dtkCore/dtkAbstractData>
#include <dtkCore/dtkAbstractDataComposite>
#include <dtkCore/dtkAbstractProcess>
#include <dtkCore/dtkGlobal>
#include <dtkCore/dtkLog>

#define DTK_DEBUG_COMPOSER_INTERACTION 1
#define DTK_DEBUG_COMPOSER_EVALUATION 1

// /////////////////////////////////////////////////////////////////
// dtkComposerNodeLoopDataCompositePrivate declaration
// /////////////////////////////////////////////////////////////////

class dtkComposerNodeLoopDataCompositePrivate
{
public:
    dtkComposerNodeControlBlock *block_loop;

public:
    dtkxarch_int from_default;
    dtkxarch_int to_default;
    dtkxarch_int step_default;

    dtkxarch_int from;
    dtkxarch_int to;
    dtkxarch_int step;
    dtkxarch_int index;

    dtkAbstractData *item;

    dtkAbstractDataComposite *composite;

    bool valid_input_composite;
};

// /////////////////////////////////////////////////////////////////
// dtkComposerNodeLoopDataComposite implementation
// /////////////////////////////////////////////////////////////////

dtkComposerNodeLoopDataComposite::dtkComposerNodeLoopDataComposite(dtkComposerNode *parent) : dtkComposerNodeLoop(parent), d(new dtkComposerNodeLoopDataCompositePrivate)
{
    d->block_loop = this->addBlock("loop");
    d->block_loop->setInteractive(false);
    d->block_loop->setHeightRatio(1);
    this->addInputProperty(d->block_loop->addInputProperty("from", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("to", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("step", dtkComposerNodeProperty::Input, dtkComposerNodeProperty::Single, dtkComposerNodeProperty::None, this));
    this->addInputProperty(d->block_loop->addInputProperty("item", dtkComposerNodeProperty::Output, dtkComposerNodeProperty::Multiple, dtkComposerNodeProperty::AsLoopInput, this));

    this->setColor(QColor("#2ABFFF"));
    this->setInputPropertyName("composite");
    this->setTitle("Composite Data Loop");
    this->setType("dtkComposerLoopDataComposite");

    d->from_default = 0;
    d->to_default = 0;
    d->step_default = 1;

    d->from = -1;
    d->to = -1;
    d->step = -1;

    d->index = 0;

    d->item = NULL;
    d->composite = NULL;

    d->valid_input_composite = false;
}

dtkComposerNodeLoopDataComposite::~dtkComposerNodeLoopDataComposite(void)
{
    delete d;

    d = NULL;
}

void dtkComposerNodeLoopDataComposite::layout(void)
{
    dtkComposerNodeControl::layout();

    QRectF  node_rect = this->boundingRect();
    qreal node_radius = this->nodeRadius();

    int j;
    qreal offset = 23;

    dtkComposerNodeControlBlock *block = this->blocks().at(0);

    block->setRect(QRectF(node_rect.x(),
                          node_rect.y() + offset,
                          node_rect.width(),
                          block->height()));

    j = 0;
    foreach(dtkComposerNodeProperty *property, block->inputProperties()) {

        property->setRect(QRectF(block->mapRectToParent(block->rect()).left() + node_radius,
                                 block->mapRectToParent(block->rect()).top()  + node_radius * (4*j + 1),
                                 2 * node_radius,
                                 2 * node_radius ));

        if (property->name() == "item") {
            property->mirror();
            j++;
        }

        j++;
    }
    j = 5;
    foreach(dtkComposerNodeProperty *property, block->outputProperties()) {

        property->setRect(QRectF(block->mapRectToParent(block->rect()).right() - node_radius * 3,
                                 block->mapRectToParent(block->rect()).top()   + node_radius * (4*j + 1),
                                 2 * node_radius,
                                 2 * node_radius ));

        j++;
    }
}

void dtkComposerNodeLoopDataComposite::update(void)
{

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
    qDebug() << DTK_PRETTY_FUNCTION << this;
#endif

    if (this->isRunning()) {

        return;

    } else {

        if (!this->dirty())
            return;

        // -- Check dirty input value

        if (this->dirtyInputValue())
            return;

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_GREEN << DTK_PRETTY_FUNCTION << "Dirty input value OK" << DTK_NO_COLOR;
#endif

        // -- Check dirty inputs

        if (this->dtkComposerNode::dirtyUpstreamNodes())
            return;

        // -- Mark dirty outputs

        this->dtkComposerNode::markDirtyDownstreamNodes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_GREEN << DTK_PRETTY_FUNCTION << "All output nodes are set to dirty" << DTK_NO_COLOR;
#endif

        // -- Clean active input routes

        this->cleanInputActiveRoutes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Input active routes cleaned" << DTK_NO_COLOR;
#endif

        // -- Pull

        foreach(dtkComposerEdge *i_route, this->inputRoutes())
            this->pull(i_route, i_route->destination());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Pull done" << DTK_NO_COLOR;
#endif

        // -- Set input composite and loop options

        foreach(dtkComposerEdge *i_route, this->inputActiveRoutes()) {
            if (i_route->destination() == this->inputProperty()) {

                dtkAbstractData *data = NULL;

                if(dtkAbstractData *dt = qobject_cast<dtkAbstractData *>(i_route->source()->node()->object())) {

                    data = dt;

                } else if(dtkAbstractProcess *process = qobject_cast<dtkAbstractProcess *>(i_route->source()->node()->object())) {

                    if(i_route->source()->node()->outputProperties().count() >= 1)
                        data = process->output(i_route->source()->node()->number(i_route->source()));
                    else
                        data = process->output();

                }

                if (data) {

                    d->composite = qobject_cast<dtkAbstractDataComposite *>(data);
                    if (!d->composite) {
                        dtkDebug() << DTK_PRETTY_FUNCTION << "input data is not of dtkAbstractDataComposite* type.";
                        return;
                    }
                    if (d->composite->count())
                        this->setObject((*d->composite)[0]);

                    d->to_default = d->composite->count()-1;

                    d->valid_input_composite = true;

                } else {

                    dtkDebug() << DTK_PRETTY_FUNCTION << "input data is not defined";
                    return;

                }

            } else if (i_route->destination()->name() == "from") {

                d->from = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "from value =" << d->from << DTK_NO_COLOR;
#endif

            } else if (i_route->destination()->name() == "to") {

                d->to = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "to value =" << d->to << DTK_NO_COLOR;
#endif

            } else if (i_route->destination()->name() == "step") {

                d->step = (dtkxarch_int)(i_route->source()->node()->value(i_route->source()).toLongLong());
#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
                qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "step value =" << d->step << DTK_NO_COLOR;
#endif

            }

            qDebug() << i_route;

        }

        if (!d->valid_input_composite) {
            dtkDebug() << DTK_PRETTY_FUNCTION << " input composite property is not connected.";
            return;
        }

        if ((d->from > d->to) && (d->from > d->to_default))
            d->from = d->to_default;
        else if (d->from < 0)
            d->from = d->from_default;
        else if (d->to < d->from && d->to < 0)
            d->to = d->from_default;
        else if (d->to > d->to_default)
            d->to = d->to_default;

        if (d->step < 0 && (d->from < d->to))
            d->step = d->step_default;

        d->index = d->from;

        // -- Running logics of conditional block

        this->setRunning(true);

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_RED  << "Loop initialization done" << DTK_NO_COLOR;
#endif

        while(d->index <= d->to) {

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
            qDebug() << DTK_COLOR_BG_RED  << "Loop is running, index = " << d->index << DTK_NO_COLOR;
#endif

            d->item = (*d->composite)[d->index];
            this->run();
            this->updatePassThroughVariables();
            d->index += d->step;

        }

        // -- Clean active output routes

        this->cleanOutputActiveRoutes();

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Output active routes cleaned" << DTK_NO_COLOR;
#endif

        // -- Push

        foreach(dtkComposerEdge *o_route, this->outputRoutes())
            this->push(o_route, o_route->source());

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_YELLOW << DTK_PRETTY_FUNCTION << "Push done" << DTK_NO_COLOR;
#endif

        // -- Forward

        this->setDirty(false);
        this->setRunning(false);

#if defined(DTK_DEBUG_COMPOSER_EVALUATION)
        qDebug() << DTK_COLOR_BG_BLUE << DTK_PRETTY_FUNCTION << "Forward done" << DTK_NO_COLOR;
#endif

        foreach(dtkComposerEdge *o_route, this->outputRoutes())
            o_route->destination()->node()->update();
    }
}

void dtkComposerNodeLoopDataComposite::onEdgeConnected(dtkComposerEdge *edge)
{
    if(true)
        edge->invalidate();
    else
        ; // dtkComposerNodeLoop::onEdgeConnected(edge);

    dtkComposerNodeLoop::onEdgeConnected(edge); // TO BE REMOVED LATER ON
}

void dtkComposerNodeLoopDataComposite::pull(dtkComposerEdge *i_route, dtkComposerNodeProperty *property)
{
    if (property->name() == "from" || property->name() == "to" || property->name() == "step")
        this->addInputActiveRoute(i_route);

    dtkComposerNodeLoop::pull(i_route, property);
}

QVariant dtkComposerNodeLoopDataComposite::value(dtkComposerNodeProperty *property)
{
    return QVariant();
}
<|endoftext|>


<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "coverage_shared.hh"

void Coverage_shared::receive_from_server()
{
  // Read number of active clients
  std::vector<std::string> tmp;

  char* s = NULL;
  size_t si = 0;
  std::vector<int> clients;

  g_io_channel_flush(d_stdin,NULL);

  while(g_main_context_iteration(NULL,FALSE));

  if (getline(&s,&si,d_stdout)<0) {
    status=false;
    return;
  }

  if (strlen(s)>2) {
    s[strlen(s)-2]='\0';
    s++;
  }

  if (!string2vector(log,s,clients,0,INT_MAX,this)) {
    status=false;
    return;
  }

  // Read each client...
  for(unsigned i=0;i<clients.size();i++) {
    if (getline(&s,&si,d_stdout)<0) {
      status=false;
      return;
    }

    if (!status) {
      continue;
    }

    // Prepare the
    if (!child->set_instance(clients[i])) {
      status=false;
      continue;
    }

    std::string name,option;

    param_cut(std::string(s),name,option);
    std::vector<std::string> p;
    commalist(option,p);

    for(unsigned j=0;status&&(j<p.size());j++) {
      std::vector<std::string> at;
      param_cut(p[j],name,option);
      commalist(option,at);
      if (at.size()!=2) {
	status=false;
	continue;
      }
      int act=atoi(at[0].c_str());
      std::vector<int> tags;
      if (!string2vector(log,at[1].c_str(),tags,0,INT_MAX,this)) {
	status=false;
      } else {
	// We should pass tags...
	child->execute(act);
      }
    }

  }

}

void Coverage_shared::communicate(int action)
{
  if (!status) {
    return;
  }
  // First, send action
  fprintf(d_stdin,"(%i,)\n",action);

  receive_from_server();
}

FACTORY_DEFAULT_CREATOR(Coverage, Coverage_shared, "shared")
<commit_msg>call child->set_instance(0) at end of receive_from_server() at coverage_shared. If it's not done, current execution is appedned to end of the last received clients execution. That's bad.<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "coverage_shared.hh"

void Coverage_shared::receive_from_server()
{
  // Read number of active clients
  std::vector<std::string> tmp;

  char* s = NULL;
  size_t si = 0;
  std::vector<int> clients;

  g_io_channel_flush(d_stdin,NULL);

  while(g_main_context_iteration(NULL,FALSE));

  if (getline(&s,&si,d_stdout)<0) {
    status=false;
    return;
  }

  if (strlen(s)>2) {
    s[strlen(s)-2]='\0';
    s++;
  }

  if (!string2vector(log,s,clients,0,INT_MAX,this)) {
    status=false;
    return;
  }

  // Read each client...
  for(unsigned i=0;i<clients.size();i++) {
    if (getline(&s,&si,d_stdout)<0) {
      status=false;
      return;
    }

    if (!status) {
      continue;
    }

    // Prepare the
    if (!child->set_instance(clients[i])) {
      status=false;
      continue;
    }

    std::string name,option;

    param_cut(std::string(s),name,option);
    std::vector<std::string> p;
    commalist(option,p);

    for(unsigned j=0;status&&(j<p.size());j++) {
      std::vector<std::string> at;
      param_cut(p[j],name,option);
      commalist(option,at);
      if (at.size()!=2) {
	status=false;
	continue;
      }
      int act=atoi(at[0].c_str());
      std::vector<int> tags;
      if (!string2vector(log,at[1].c_str(),tags,0,INT_MAX,this)) {
	status=false;
      } else {
	// We should pass tags...
	child->execute(act);
      }
    }

  }
  child->set_instance(0);
}

void Coverage_shared::communicate(int action)
{
  if (!status) {
    return;
  }
  // First, send action
  fprintf(d_stdin,"(%i,)\n",action);

  receive_from_server();
}

FACTORY_DEFAULT_CREATOR(Coverage, Coverage_shared, "shared")
<|endoftext|>


<commit_before>// Copyright (c) 2016 Ansho Enigu
#include "crypto/lamport.h"

#include "crypto/ripemd160.h"
#include "crypto/common.h"
#include "uint256.h"
bool LAMPORT::checksig(unsigned char data[10000], char sig[20][2][20], char rootkey[20], char merklewit[])
{

  char exmerklewit[8][20]; /*this is the merkle wit minus the main public key max number of publickeys to rootkey is 256 due to 2^n where n is the first array index is 8*/
  char pubkey[20][2][20];
  bool merklecheckfin = false;

  //start converting merkle wit to exmerklewit and public key
  char merklebuffer[800]; //size of publickey is the max size of the buffer
  unsigned int i;
  for(i = 0; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00) /*test for partition beetween merkle segments*/
      break;
    merklebuffer[i] = merklewit[i];
  }

  memcpy(&pubkey, &merklebuffer, sizeof(merklebuffer));
  int o = 0;
  int r = 0; //number of times we have reset o count
  for(; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00)
    {
      memcpy(&exmerklewit[r], &merklebuffer, sizeof(merklebuffer));
      r++;
      i++; //get i+1 index chunk so we can jump to next part of the merklewit at the end of cycle
      o = 0;
    }
    else
    {
      merklebuffer[o] = merklewit[i];
      o++;
    }
  }
  //end decoding merkle wit format

  //start checking if new publickey is a part of the root key
  for(int i = 0; !merklecheckfin; i++) //to end if false we will use return to lower processing time
  {
    return false;
  }
  //end checking if new publickey is a part of the root key

  /*
      unsigned char* datapart;
      unsigned char[(160/LAMPORT::chuncksize)]* datahashs;
      for(int i = 0; i < (160/LAMPORT::chuncksize); i++)
      {

        for(int o = 0; o < chuncksizeinbyte; o++)
        {
          datapart[o] = data[(i * LAMPORT::chuncksize) + o];
        }

        CRIPEMD160().Write(begin_ptr(datapart), datapart.size()).Finalize(begin_ptr(datahashs[i]));
      }
      */
      return true; // if compleats all tests return true
}
    char *** LAMPORT::createsig(unsigned char data[10000], uint512_t prikey, int sellectedpubkey)
    {
      /* hash of the message */
      bool messhashb[160];
      unsigned char messhash[20];
      CRIPEMD160().Write(&data, 10000).Finalize(&messhash);

      /* creating true key from seed (the seed is used as the key by the user but it only is a form of compress key) */
      unsigned char[20] vchHash
      unsigned char[64] prikeychar;

      memcpy(&prikeychar, &prikey, 64);

      CRIPEMD160().Write(&prikeychar, 64).Finalize(&vchHash);
      char temphash[20];

      char ichar;
      for(int i =0; i < 320; i++)
      {
        memcpy(&ichar, &i, 1);
        CRIPEMD160().Write(&vchHash, sizeof(vchHash)).Write(&ichar, sizeof(ichar)).Finalize(&temphash);
        prikeys[i] = temphash;
      }

      /* the signing will happen under this */
      char sig[20][2][20];

      return &sig;
    }
<commit_msg>Update lamport.cpp<commit_after>// Copyright (c) 2016 Ansho Enigu
#include "crypto/lamport.h"

#include "crypto/ripemd160.h"
#include "crypto/common.h"
#include "uint256.h"
bool LAMPORT::checksig(unsigned char data[10000], char sig[20][2][20], char rootkey[20], char merklewit[])
{

  char exmerklewit[8][20]; /*this is the merkle wit minus the main public key max number of publickeys to rootkey is 256 due to 2^n where n is the first array index is 8*/
  char pubkey[20][2][20];
  bool merklecheckfin = false;

  //start converting merkle wit to exmerklewit and public key
  char merklebuffer[800]; //size of publickey is the max size of the buffer
  unsigned int i;
  for(i = 0; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00) /*test for partition beetween merkle segments*/
      break;
    merklebuffer[i] = merklewit[i];
  }

  memcpy(&pubkey, &merklebuffer, sizeof(merklebuffer));
  int o = 0;
  int r = 0; //number of times we have reset o count
  for(; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00)
    {
      memcpy(&exmerklewit[r], &merklebuffer, sizeof(merklebuffer));
      r++;
      i++; //get i+1 index chunk so we can jump to next part of the merklewit at the end of cycle
      o = 0;
    }
    else
    {
      merklebuffer[o] = merklewit[i];
      o++;
    }
  }
  //end decoding merkle wit format

  //start checking if new publickey is a part of the root key
  for(int i = 0; !merklecheckfin; i++) //to end if false we will use return to lower processing time
  {
    return false;
  }
  //end checking if new publickey is a part of the root key

  /*
      unsigned char* datapart;
      unsigned char[(160/LAMPORT::chuncksize)]* datahashs;
      for(int i = 0; i < (160/LAMPORT::chuncksize); i++)
      {

        for(int o = 0; o < chuncksizeinbyte; o++)
        {
          datapart[o] = data[(i * LAMPORT::chuncksize) + o];
        }

        CRIPEMD160().Write(begin_ptr(datapart), datapart.size()).Finalize(begin_ptr(datahashs[i]));
      }
      */
      return true; // if compleats all tests return true
}
    char *** LAMPORT::createsig(unsigned char data[10000], uint512_t prikey, int sellectedpubkey)
    {
      /* hash of the message */
      bool messhashb[160];
      unsigned char messhash[20];
      CRIPEMD160().Write(&data, 10000).Finalize(&messhash);

      /* creating true key from seed (the seed is used as the key by the user but it only is a form of compress key) */
      unsigned char vchHash[20];
      unsigned char prikeychar[64];

      memcpy(&prikeychar, &prikey, 64);

      CRIPEMD160().Write(&prikeychar, 64).Finalize(&vchHash);
      char temphash[20];

      char ichar;
      for(int i =0; i < 320; i++)
      {
        memcpy(&ichar, &i, 1);
        CRIPEMD160().Write(&vchHash, sizeof(vchHash)).Write(&ichar, sizeof(ichar)).Finalize(&temphash);
        memcpy(&prikeys[i], &temphash, sizeof(temphash));
      }

      /* the signing will happen under this */
      char sig[20][2][20];

      return &sig;
    }
<|endoftext|>


<commit_before>#include <cmath>
#include <string>
#include <ros/ros.h>
#include <dynamic_reconfigure/server.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <std_msgs/Float64.h>

#include <jaguar/diff_drive.h>
#include <jaguar/JaguarConfig.h>

using namespace can;
using namespace jaguar;

static ros::Subscriber sub_twist;
static ros::Publisher pub_odom;
static ros::Publisher pub_vleft, pub_vright;

static DiffDriveSettings settings;
static boost::shared_ptr<DiffDriveRobot> robot;
static boost::shared_ptr<tf::TransformBroadcaster> pub_tf;
static std::string frame_parent;
static std::string frame_child;

void callback_odom(double x,  double y,  double theta,
                   double vx, double vy, double omega)
{
    ros::Time now = ros::Time::now();

    // odom TF Frame
    geometry_msgs::TransformStamped msg_tf;
    msg_tf.header.stamp = now;
    msg_tf.header.frame_id = frame_parent;
    msg_tf.child_frame_id  = frame_child;
    msg_tf.transform.translation.x = x;
    msg_tf.transform.translation.y = y;
    msg_tf.transform.rotation = tf::createQuaternionMsgFromYaw(theta);
    pub_tf->sendTransform(msg_tf);

    // Odometry Message
    nav_msgs::Odometry msg_odom;
    msg_odom.header.stamp = now;
    msg_odom.header.frame_id = frame_parent;
    msg_odom.child_frame_id  = frame_child;
    msg_odom.pose.pose.position.x = x;
    msg_odom.pose.pose.position.y = y;
    msg_odom.pose.pose.orientation = tf::createQuaternionMsgFromYaw(theta);
    msg_odom.twist.twist.linear.x = vx;
    msg_odom.twist.twist.linear.y = vy;
    msg_odom.twist.twist.angular.z = omega;
    pub_odom.publish(msg_odom);
}

void callback_speed(DiffDriveRobot::Side side, double speed)
{
    std_msgs::Float64 msg;
    msg.data = speed;

    switch (side) {
    case DiffDriveRobot::kLeft:
        pub_vleft.publish(msg);
        break;

    case DiffDriveRobot::kRight:
        pub_vright.publish(msg);
        break;

    default:
        ROS_WARN_THROTTLE(10, "Invalid speed callback.");
    }
}

void callback_cmd(geometry_msgs::Twist const &twist)
{
    if (twist.linear.y  != 0.0 || twist.linear.z  != 0
     || twist.angular.x != 0.0 || twist.angular.y != 0) {
        ROS_WARN_THROTTLE(10.0, "Ignoring non-zero component of velocity command.");
    }
    robot->drive(twist.linear.x, twist.angular.z);
}

void callback_reconfigure(jaguar::JaguarConfig &config, uint32_t level)
{
    // Speed Control Gains
    if (level & 1) {
        robot->speed_set_p(config.gain_p);
        ROS_INFO("Reconfigure, P = %f", config.gain_p);
    }
    if (level & 2) {
        robot->speed_set_i(config.gain_i);
        ROS_INFO("Reconfigure, I = %f", config.gain_i);
    }
    if (level & 4) {
        robot->speed_set_d(config.gain_d);
        ROS_INFO("Reconfigure, D = %f", config.gain_d);
    }
    if (level & 8) {
        robot->drive_brake(config.brake);
        ROS_INFO("Reconfigure, Braking = %d", config.brake);
    }
    if (level & 16) {
        if (0 < config.ticks_per_rev && config.ticks_per_rev <= std::numeric_limits<uint16_t>::max()) {
            robot->robot_set_encoders(config.ticks_per_rev);
            ROS_INFO("Reconfigure, Ticks/Rev = %d", config.ticks_per_rev);
        } else {
            ROS_WARN("Ticks/rev must be a positive 16-bit unsigned integer.");
        }
    }
    if (level & 32) {
        if (config.wheel_radius <= 0) {
            ROS_WARN("Wheel radius must be positive.");
        } else if (config.robot_radius <= 0) {
            ROS_WARN("Robot radius must be positive.");
        } else {
            robot->robot_set_radii(config.wheel_radius, config.robot_radius);
            ROS_INFO("Reconfigure, Wheel Radius = %f m and Robot Radius = %f m",
                config.wheel_radius, config.robot_radius
            );
        }
    }
    if (level & 64) {
        robot->drive_raw(config.setpoint, config.setpoint);
        ROS_INFO("Reconfigure, Setpoint = %f", config.setpoint);
    }
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "diff_drive_node");
    ros::NodeHandle nh;

    int ticks_per_rev;
    ros::param::get("~port", settings.port);
    ros::param::get("~id_left", settings.id_left);
    ros::param::get("~id_right", settings.id_right);
    ros::param::get("~heartbeat", settings.heartbeat_ms);
    ros::param::get("~status", settings.status_ms);
    ros::param::get("~frame_parent", frame_parent);
    ros::param::get("~frame_child", frame_child);
    ros::param::get("~accel_max", settings.accel_max_mps2);
    settings.ticks_per_rev = static_cast<uint16_t>(ticks_per_rev);

    ROS_INFO("Port: %s", settings.port.c_str());
    ROS_INFO("ID Left: %d", settings.id_left);
    ROS_INFO("ID Right: %d", settings.id_right);
    ROS_INFO("Heartbeat Rate: %d ms", settings.heartbeat_ms);
    ROS_INFO("Status Rate: %d ms", settings.status_ms);

    // TODO: Read this from a parameter.
    settings.brake = BrakeCoastSetting::kOverrideCoast;

    if (!(1 <= settings.id_left  && settings.id_left  <= 63)
     || !(1 <= settings.id_right && settings.id_right <= 63)) {
        ROS_FATAL("Invalid CAN device id. Must be in the range 1-63.");
        return 1;
    } else if (settings.heartbeat_ms <= 0 || settings.heartbeat_ms > 100) {
        ROS_FATAL("Heartbeat period invalid. Must be in the range 1-500 ms.");
        return 1;
    } else if (settings.status_ms <= 0 || settings.status_ms > std::numeric_limits<uint16_t>::max()) {
        ROS_FATAL("Status period invalid must be in the range 1-255 ms.");
        return 1;
    } else if (ticks_per_rev <= 0) {
        ROS_FATAL("Number of ticks per revolution must be positive");
        return 1;
    } else if (settings.wheel_radius_m <= 0) {
        ROS_FATAL("Wheel radius must be positive.");
        return 1;
    } else if (settings.robot_radius_m <= 0) {
        ROS_FATAL("Robot radius must be positive.");
        return 1;
    }

    // This must be done first because the asynchronous encoder callbacks use
    // the transform broadcaster.
    sub_twist = nh.subscribe("cmd_vel", 1, &callback_cmd);
    pub_odom  = nh.advertise<nav_msgs::Odometry>("odom", 100);
    pub_vleft  = nh.advertise<std_msgs::Float64>("encoder_left", 100);
    pub_vright = nh.advertise<std_msgs::Float64>("encoder_right", 100);
    pub_tf = boost::make_shared<tf::TransformBroadcaster>();

    dynamic_reconfigure::Server<jaguar::JaguarConfig> server;
    dynamic_reconfigure::Server<jaguar::JaguarConfig>::CallbackType f;
    f = boost::bind(&callback_reconfigure, _1, _2);
    server.setCallback(f);

    robot = boost::make_shared<DiffDriveRobot>(settings);
    robot->odom_attach(&callback_odom);
    robot->speed_attach(&callback_speed);

    // TODO: Read this heartbeat rate from a parameter.
    ros::Rate heartbeat_rate(50);
    while (ros::ok()) {
        robot->drive_spin(1 / 50.);
        robot->heartbeat();
        ros::spinOnce();
        heartbeat_rate.sleep();
    }
    return 0;
}
<commit_msg>removed unused variable<commit_after>#include <cmath>
#include <string>
#include <ros/ros.h>
#include <dynamic_reconfigure/server.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <std_msgs/Float64.h>

#include <jaguar/diff_drive.h>
#include <jaguar/JaguarConfig.h>

using namespace can;
using namespace jaguar;

static ros::Subscriber sub_twist;
static ros::Publisher pub_odom;
static ros::Publisher pub_vleft, pub_vright;

static DiffDriveSettings settings;
static boost::shared_ptr<DiffDriveRobot> robot;
static boost::shared_ptr<tf::TransformBroadcaster> pub_tf;
static std::string frame_parent;
static std::string frame_child;

void callback_odom(double x,  double y,  double theta,
                   double vx, double vy, double omega)
{
    ros::Time now = ros::Time::now();

    // odom TF Frame
    geometry_msgs::TransformStamped msg_tf;
    msg_tf.header.stamp = now;
    msg_tf.header.frame_id = frame_parent;
    msg_tf.child_frame_id  = frame_child;
    msg_tf.transform.translation.x = x;
    msg_tf.transform.translation.y = y;
    msg_tf.transform.rotation = tf::createQuaternionMsgFromYaw(theta);
    pub_tf->sendTransform(msg_tf);

    // Odometry Message
    nav_msgs::Odometry msg_odom;
    msg_odom.header.stamp = now;
    msg_odom.header.frame_id = frame_parent;
    msg_odom.child_frame_id  = frame_child;
    msg_odom.pose.pose.position.x = x;
    msg_odom.pose.pose.position.y = y;
    msg_odom.pose.pose.orientation = tf::createQuaternionMsgFromYaw(theta);
    msg_odom.twist.twist.linear.x = vx;
    msg_odom.twist.twist.linear.y = vy;
    msg_odom.twist.twist.angular.z = omega;
    pub_odom.publish(msg_odom);
}

void callback_speed(DiffDriveRobot::Side side, double speed)
{
    std_msgs::Float64 msg;
    msg.data = speed;

    switch (side) {
    case DiffDriveRobot::kLeft:
        pub_vleft.publish(msg);
        break;

    case DiffDriveRobot::kRight:
        pub_vright.publish(msg);
        break;

    default:
        ROS_WARN_THROTTLE(10, "Invalid speed callback.");
    }
}

void callback_cmd(geometry_msgs::Twist const &twist)
{
    if (twist.linear.y  != 0.0 || twist.linear.z  != 0
     || twist.angular.x != 0.0 || twist.angular.y != 0) {
        ROS_WARN_THROTTLE(10.0, "Ignoring non-zero component of velocity command.");
    }
    robot->drive(twist.linear.x, twist.angular.z);
}

void callback_reconfigure(jaguar::JaguarConfig &config, uint32_t level)
{
    // Speed Control Gains
    if (level & 1) {
        robot->speed_set_p(config.gain_p);
        ROS_INFO("Reconfigure, P = %f", config.gain_p);
    }
    if (level & 2) {
        robot->speed_set_i(config.gain_i);
        ROS_INFO("Reconfigure, I = %f", config.gain_i);
    }
    if (level & 4) {
        robot->speed_set_d(config.gain_d);
        ROS_INFO("Reconfigure, D = %f", config.gain_d);
    }
    if (level & 8) {
        robot->drive_brake(config.brake);
        ROS_INFO("Reconfigure, Braking = %d", config.brake);
    }
    if (level & 16) {
        if (0 < config.ticks_per_rev && config.ticks_per_rev <= std::numeric_limits<uint16_t>::max()) {
            robot->robot_set_encoders(config.ticks_per_rev);
            ROS_INFO("Reconfigure, Ticks/Rev = %d", config.ticks_per_rev);
        } else {
            ROS_WARN("Ticks/rev must be a positive 16-bit unsigned integer.");
        }
    }
    if (level & 32) {
        if (config.wheel_radius <= 0) {
            ROS_WARN("Wheel radius must be positive.");
        } else if (config.robot_radius <= 0) {
            ROS_WARN("Robot radius must be positive.");
        } else {
            robot->robot_set_radii(config.wheel_radius, config.robot_radius);
            ROS_INFO("Reconfigure, Wheel Radius = %f m and Robot Radius = %f m",
                config.wheel_radius, config.robot_radius
            );
        }
    }
    if (level & 64) {
        robot->drive_raw(config.setpoint, config.setpoint);
        ROS_INFO("Reconfigure, Setpoint = %f", config.setpoint);
    }
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "diff_drive_node");
    ros::NodeHandle nh;

    ros::param::get("~port", settings.port);
    ros::param::get("~id_left", settings.id_left);
    ros::param::get("~id_right", settings.id_right);
    ros::param::get("~heartbeat", settings.heartbeat_ms);
    ros::param::get("~status", settings.status_ms);
    ros::param::get("~frame_parent", frame_parent);
    ros::param::get("~frame_child", frame_child);
    ros::param::get("~accel_max", settings.accel_max_mps2);

    ROS_INFO("Port: %s", settings.port.c_str());
    ROS_INFO("ID Left: %d", settings.id_left);
    ROS_INFO("ID Right: %d", settings.id_right);
    ROS_INFO("Heartbeat Rate: %d ms", settings.heartbeat_ms);
    ROS_INFO("Status Rate: %d ms", settings.status_ms);

    // TODO: Read this from a parameter.
    settings.brake = BrakeCoastSetting::kOverrideCoast;

    if (!(1 <= settings.id_left  && settings.id_left  <= 63)
     || !(1 <= settings.id_right && settings.id_right <= 63)) {
        ROS_FATAL("Invalid CAN device id. Must be in the range 1-63.");
        return 1;
    } else if (settings.heartbeat_ms <= 0 || settings.heartbeat_ms > 100) {
        ROS_FATAL("Heartbeat period invalid. Must be in the range 1-500 ms.");
        return 1;
    } else if (settings.status_ms <= 0 || settings.status_ms > std::numeric_limits<uint16_t>::max()) {
        ROS_FATAL("Status period invalid must be in the range 1-255 ms.");
        return 1;
    } else if (ticks_per_rev <= 0) {
        ROS_FATAL("Number of ticks per revolution must be positive");
        return 1;
    } else if (settings.wheel_radius_m <= 0) {
        ROS_FATAL("Wheel radius must be positive.");
        return 1;
    } else if (settings.robot_radius_m <= 0) {
        ROS_FATAL("Robot radius must be positive.");
        return 1;
    }

    // This must be done first because the asynchronous encoder callbacks use
    // the transform broadcaster.
    sub_twist = nh.subscribe("cmd_vel", 1, &callback_cmd);
    pub_odom  = nh.advertise<nav_msgs::Odometry>("odom", 100);
    pub_vleft  = nh.advertise<std_msgs::Float64>("encoder_left", 100);
    pub_vright = nh.advertise<std_msgs::Float64>("encoder_right", 100);
    pub_tf = boost::make_shared<tf::TransformBroadcaster>();

    dynamic_reconfigure::Server<jaguar::JaguarConfig> server;
    dynamic_reconfigure::Server<jaguar::JaguarConfig>::CallbackType f;
    f = boost::bind(&callback_reconfigure, _1, _2);
    server.setCallback(f);

    robot = boost::make_shared<DiffDriveRobot>(settings);
    robot->odom_attach(&callback_odom);
    robot->speed_attach(&callback_speed);

    // TODO: Read this heartbeat rate from a parameter.
    ros::Rate heartbeat_rate(50);
    while (ros::ok()) {
        robot->drive_spin(1 / 50.);
        robot->heartbeat();
        ros::spinOnce();
        heartbeat_rate.sleep();
    }
    return 0;
}
<|endoftext|>


<commit_before>#ifndef _SNARKFRONT_COMPILE_QAP_HPP_
#define _SNARKFRONT_COMPILE_QAP_HPP_

#include <array>
#include <cstdint>
#include <fstream>
#include <functional>
#include <string>

// snarklib
#include <AuxSTL.hpp>
#include <HugeSystem.hpp>
#include <IndexSpace.hpp>
#include <PPZK_randomness.hpp>
#include <QAP_query.hpp>
#include <QAP_system.hpp>
#include <QAP_witness.hpp>
#include <Rank1DSL.hpp>
#include <Util.hpp>

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// query ABCH
//

template <typename PAIRING>
class QAP_query_ABCH
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_QueryABC<snarklib::HugeSystem, FR> Q_ABC;
    typedef typename snarklib::QAP_QueryH<snarklib::HugeSystem, FR> Q_H;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_ABCH(const std::size_t numBlocks,
                   const std::string& sysfile,
                   const std::string& randfile)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    // for g1_exp_count() and g2_exp_count() only
    QAP_query_ABCH(const std::string& sysfile)
        : m_numBlocks(0),
          m_hugeSystem(sysfile)
    {
        m_error = !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void A(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::A);
    }

    void B(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::B);
    }

    void C(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::C);
    }

    void H(const std::string& outfile) {
        writeFilesH(outfile);
    }

    std::size_t g1_exp_count(const std::string& afile,
                             const std::string& bfile,
                             const std::string& cfile,
                             const std::string& hfile) {
        return snarklib::g1_exp_count(
            m_hugeSystem.maxIndex(),         // same as QAP numVariables()
            m_hugeSystem.numCircuitInputs(), // same as QAP numCircuitInputs()
            nonzeroCount(afile),
            nonzeroCount(bfile),
            nonzeroCount(cfile),
            nonzeroCount(hfile));
    }

    std::size_t g2_exp_count(const std::string& bfile) {
        return snarklib::g2_exp_count(
            nonzeroCount(bfile));
    }

private:
    template <typename QUERY>
    void writeFiles(const std::string& outfile,
                    std::function<QUERY (const SYSPT&)> func)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        const auto Q = func(qap);

        auto space = snarklib::BlockVector<FR>::space(Q.vec());
        space.blockPartition(std::array<size_t, 1>{m_numBlocks});
        space.param(Q.nonzeroCount());

        std::ofstream ofs(outfile);
        if (!ofs || !write_blockvector(outfile, space, Q.vec()))
            m_error = true;
        else
            space.marshal_out(ofs);
    }

    void writeFilesABC(const std::string& outfile,
                       const unsigned int mask) {
        writeFiles<Q_ABC>(
            outfile,
            [&mask] (const SYSPT& qap) { return Q_ABC(qap, mask); });
    }

    void writeFilesH(const std::string& outfile) {
        writeFiles<Q_H>(
            outfile,
            [] (const SYSPT& qap) { return Q_H(qap); });
    }

    std::size_t nonzeroCount(const std::string& abchfile) {
        snarklib::IndexSpace<1> space;
        std::ifstream ifs(abchfile);
        return (!ifs || !space.marshal_in(ifs))
            ? m_error = false
            : space.param()[0];
    }

    const std::size_t m_numBlocks;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// query K
//

template <typename PAIRING>
class QAP_query_K
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_K(const std::string& afile,
                const std::string& bfile,
                const std::string& cfile,
                const std::string& sysfile,
                const std::string& randfile)
        : m_afile(afile),
          m_bfile(bfile),
          m_cfile(cfile),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_clearGreeks.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void K(const std::string& outfile,
           const std::size_t blocknum) {
        writeFiles(outfile, blocknum);
    }

private:
    void writeFiles(const std::string& outfile,
                    const std::size_t blocknum)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        snarklib::QAP_QueryK<FR> Q(qap,
                                   m_clearGreeks.beta_rA(),
                                   m_clearGreeks.beta_rB(),
                                   m_clearGreeks.beta_rC());

        std::size_t block = (-1 == blocknum) ? 0 : blocknum;
        bool b = true;
        while (b) {
            snarklib::BlockVector<FR> A, B, C;

            if (!snarklib::read_blockvector(m_afile, block, A) ||
                !snarklib::read_blockvector(m_bfile, block, B) ||
                !snarklib::read_blockvector(m_cfile, block, C)) {
                m_error = true;
                return;
            }

            const auto& space = A.space();

            Q.accumVector(A, B, C);

            if (!snarklib::write_blockvector(outfile, block, space, Q.vec())) {
                m_error = true;
                return;
            }

            b = (-1 == blocknum)
                ? ++block < space.blockID()[0]
                : false;

            if (!b) {
                std::ofstream ofs(outfile);
                if (!ofs)
                    m_error = true;
                else
                    space.marshal_out(ofs);
            }
        }
    }

    const std::string m_afile, m_bfile, m_cfile;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::PPZK_BlindGreeks<FR, FR> m_clearGreeks;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// query IC
//

template <typename PAIRING>
class QAP_query_IC
{
    typedef typename PAIRING::Fr FR;
    typedef typename PAIRING::G1 G1;
    typedef typename PAIRING::G2 G2;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_IC(const std::string& afile, // side-effect: file is modified
                 const std::string& sysfile,
                 const std::string& randfile)
        : m_afile(afile),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void IC(const std::string& outfile) {
        writeFiles(outfile);
    }

private:
    void writeFiles(const std::string& outfile) {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        snarklib::QAP_QueryIC<FR> Q(qap);

        std::size_t block = 0;
        bool b = true;
        while (b) {
            snarklib::BlockVector<FR> A;

            if (!snarklib::read_blockvector(m_afile, block, A)) {
                m_error = true;
                return;
            }

            if (!Q.accumVector(A)) break;

            std::stringstream ss;
            ss << m_afile << block;

            std::ofstream ofs(ss.str());
            if (!ofs)
                m_error = true;
            else
                A.marshal_out(ofs); // side-effect: write back to file

            b = ++block < A.space().blockID()[0];
        }

        std::ofstream ofs(outfile);
        const auto space = snarklib::BlockVector<FR>::space(Q.vec());
        if (!ofs || !snarklib::write_blockvector(outfile, space, Q.vec()))
            m_error = true;
        else
            space.marshal_out(ofs);
    }

    const std::string m_afile;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// witness ABCH
//

template <typename PAIRING>
class QAP_witness_ABCH
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_witness_ABCH(const std::size_t numBlocks,
                     const std::string& sysfile,
                     const std::string& randfile,
                     const std::string& witfile)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifsR(randfile), ifsW(witfile);
        m_error =
            !ifsR || !m_randomness.marshal_in(ifsR) ||
            !ifsW || !m_witness.marshal_in(ifsW) ||
            !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void writeFiles(const std::string& outfile)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs());

        const snarklib::QAP_WitnessABCH<snarklib::HugeSystem, FR>
            ABCH(qap,
                 m_witness,
                 m_randomness.d1(),
                 m_randomness.d2(),
                 m_randomness.d3());

        auto space = snarklib::BlockVector<FR>::space(ABCH.vec());
        space.blockPartition(std::array<size_t, 1>{m_numBlocks});

        if (! write_blockvector(outfile, space, ABCH.vec()))
            m_error = true;
    }

private:
    const std::size_t m_numBlocks;

    snarklib::R1Witness<FR> m_witness;
    snarklib::PPZK_ProofRandomness<FR> m_randomness;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

} // namespace snarkfront

#endif
<commit_msg>constructor randomness arguments<commit_after>#ifndef _SNARKFRONT_COMPILE_QAP_HPP_
#define _SNARKFRONT_COMPILE_QAP_HPP_

#include <array>
#include <cstdint>
#include <fstream>
#include <functional>
#include <string>

// snarklib
#include <AuxSTL.hpp>
#include <HugeSystem.hpp>
#include <IndexSpace.hpp>
#include <PPZK_randomness.hpp>
#include <QAP_query.hpp>
#include <QAP_system.hpp>
#include <QAP_witness.hpp>
#include <Rank1DSL.hpp>
#include <Util.hpp>

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// query ABCH
//

template <typename PAIRING>
class QAP_query_ABCH
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_QueryABC<snarklib::HugeSystem, FR> Q_ABC;
    typedef typename snarklib::QAP_QueryH<snarklib::HugeSystem, FR> Q_H;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_ABCH(const std::size_t numBlocks,
                   const std::string& sysfile,
                   const std::string& randfile)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    QAP_query_ABCH(const std::size_t numBlocks,
                   const std::string& sysfile,
                   const snarklib::PPZK_LagrangePoint<FR>& lagrangeRand)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile),
          m_lagrangePoint(lagrangeRand)
    {
        m_error = !m_hugeSystem.loadIndex();
    }

    // for g1_exp_count() and g2_exp_count() only
    QAP_query_ABCH(const std::string& sysfile)
        : m_numBlocks(0),
          m_hugeSystem(sysfile)
    {
        m_error = !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void A(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::A);
    }

    void B(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::B);
    }

    void C(const std::string& outfile) {
        writeFilesABC(outfile, Q_ABC::VecSelect::C);
    }

    void H(const std::string& outfile) {
        writeFilesH(outfile);
    }

    std::size_t g1_exp_count(const std::string& afile,
                             const std::string& bfile,
                             const std::string& cfile,
                             const std::string& hfile) {
        return snarklib::g1_exp_count(
            m_hugeSystem.maxIndex(),         // same as QAP numVariables()
            m_hugeSystem.numCircuitInputs(), // same as QAP numCircuitInputs()
            nonzeroCount(afile),
            nonzeroCount(bfile),
            nonzeroCount(cfile),
            nonzeroCount(hfile));
    }

    std::size_t g2_exp_count(const std::string& bfile) {
        return snarklib::g2_exp_count(
            nonzeroCount(bfile));
    }

private:
    template <typename QUERY>
    void writeFiles(const std::string& outfile,
                    std::function<QUERY (const SYSPT&)> func)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        const auto Q = func(qap);

        auto space = snarklib::BlockVector<FR>::space(Q.vec());
        space.blockPartition(std::array<size_t, 1>{m_numBlocks});
        space.param(Q.nonzeroCount());

        std::ofstream ofs(outfile);
        if (!ofs || !write_blockvector(outfile, space, Q.vec()))
            m_error = true;
        else
            space.marshal_out(ofs);
    }

    void writeFilesABC(const std::string& outfile,
                       const unsigned int mask) {
        writeFiles<Q_ABC>(
            outfile,
            [&mask] (const SYSPT& qap) { return Q_ABC(qap, mask); });
    }

    void writeFilesH(const std::string& outfile) {
        writeFiles<Q_H>(
            outfile,
            [] (const SYSPT& qap) { return Q_H(qap); });
    }

    std::size_t nonzeroCount(const std::string& abchfile) {
        snarklib::IndexSpace<1> space;
        std::ifstream ifs(abchfile);
        return (!ifs || !space.marshal_in(ifs))
            ? m_error = false
            : space.param()[0];
    }

    const std::size_t m_numBlocks;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// query K
//

template <typename PAIRING>
class QAP_query_K
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_K(const std::string& afile,
                const std::string& bfile,
                const std::string& cfile,
                const std::string& sysfile,
                const std::string& randfile)
        : m_afile(afile),
          m_bfile(bfile),
          m_cfile(cfile),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_clearGreeks.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    QAP_query_K(const std::string& afile,
                const std::string& bfile,
                const std::string& cfile,
                const std::string& sysfile,
                const snarklib::PPZK_LagrangePoint<FR>& lagrangeRand,
                const snarklib::PPZK_BlindGreeks<FR, FR>& greeksRand)
        : m_afile(afile),
          m_bfile(bfile),
          m_cfile(cfile),
          m_hugeSystem(sysfile),
          m_lagrangePoint(lagrangeRand),
          m_clearGreeks(greeksRand)
    {
        m_error = !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void K(const std::string& outfile,
           const std::size_t blocknum) {
        writeFiles(outfile, blocknum);
    }

private:
    void writeFiles(const std::string& outfile,
                    const std::size_t blocknum)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        snarklib::QAP_QueryK<FR> Q(qap,
                                   m_clearGreeks.beta_rA(),
                                   m_clearGreeks.beta_rB(),
                                   m_clearGreeks.beta_rC());

        std::size_t block = (-1 == blocknum) ? 0 : blocknum;
        bool b = true;
        while (b) {
            snarklib::BlockVector<FR> A, B, C;

            if (!snarklib::read_blockvector(m_afile, block, A) ||
                !snarklib::read_blockvector(m_bfile, block, B) ||
                !snarklib::read_blockvector(m_cfile, block, C)) {
                m_error = true;
                return;
            }

            const auto& space = A.space();

            Q.accumVector(A, B, C);

            if (!snarklib::write_blockvector(outfile, block, space, Q.vec())) {
                m_error = true;
                return;
            }

            b = (-1 == blocknum)
                ? ++block < space.blockID()[0]
                : false;

            if (!b) {
                std::ofstream ofs(outfile);
                if (!ofs)
                    m_error = true;
                else
                    space.marshal_out(ofs);
            }
        }
    }

    const std::string m_afile, m_bfile, m_cfile;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::PPZK_BlindGreeks<FR, FR> m_clearGreeks;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// query IC
//

template <typename PAIRING>
class QAP_query_IC
{
    typedef typename PAIRING::Fr FR;
    typedef typename PAIRING::G1 G1;
    typedef typename PAIRING::G2 G2;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_query_IC(const std::string& afile, // side-effect: file is modified
                 const std::string& sysfile,
                 const std::string& randfile)
        : m_afile(afile),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifs(randfile);
        m_error = !ifs ||
            !m_lagrangePoint.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    QAP_query_IC(const std::string& afile, // side-effect: file is modified
                 const std::string& sysfile,
                 const snarklib::PPZK_LagrangePoint<FR>& lagrangeRand)
        : m_afile(afile),
          m_hugeSystem(sysfile),
          m_lagrangePoint(lagrangeRand)
    {
        m_error = !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void IC(const std::string& outfile) {
        writeFiles(outfile);
    }

private:
    void writeFiles(const std::string& outfile) {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs(),
                        m_lagrangePoint.point());

        snarklib::QAP_QueryIC<FR> Q(qap);

        std::size_t block = 0;
        bool b = true;
        while (b) {
            snarklib::BlockVector<FR> A;

            if (!snarklib::read_blockvector(m_afile, block, A)) {
                m_error = true;
                return;
            }

            if (!Q.accumVector(A)) break;

            std::stringstream ss;
            ss << m_afile << block;

            std::ofstream ofs(ss.str());
            if (!ofs)
                m_error = true;
            else
                A.marshal_out(ofs); // side-effect: write back to file

            b = ++block < A.space().blockID()[0];
        }

        std::ofstream ofs(outfile);
        const auto space = snarklib::BlockVector<FR>::space(Q.vec());
        if (!ofs || !snarklib::write_blockvector(outfile, space, Q.vec()))
            m_error = true;
        else
            space.marshal_out(ofs);
    }

    const std::string m_afile;

    snarklib::PPZK_LagrangePoint<FR> m_lagrangePoint;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

////////////////////////////////////////////////////////////////////////////////
// witness ABCH
//

template <typename PAIRING>
class QAP_witness_ABCH
{
    typedef typename PAIRING::Fr FR;
    typedef typename snarklib::QAP_SystemPoint<snarklib::HugeSystem, FR> SYSPT;

public:
    QAP_witness_ABCH(const std::size_t numBlocks,
                     const std::string& sysfile,
                     const std::string& randfile,
                     const std::string& witfile)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile)
    {
        std::ifstream ifsR(randfile), ifsW(witfile);
        m_error =
            !ifsR || !m_randomness.marshal_in(ifsR) ||
            !ifsW || !m_witness.marshal_in(ifsW) ||
            !m_hugeSystem.loadIndex();
    }

    QAP_witness_ABCH(const std::size_t numBlocks,
                     const std::string& sysfile,
                     const snarklib::PPZK_ProofRandomness<FR>& proofRand,
                     const std::string& witfile)
        : m_numBlocks(numBlocks),
          m_hugeSystem(sysfile),
          m_randomness(proofRand)
    {
        std::ifstream ifs(witfile);
        m_error =
            !ifs || !m_witness.marshal_in(ifs) ||
            !m_hugeSystem.loadIndex();
    }

    bool operator! () const { return m_error; }

    void writeFiles(const std::string& outfile)
    {
        const SYSPT qap(m_hugeSystem,
                        m_hugeSystem.numCircuitInputs());

        const snarklib::QAP_WitnessABCH<snarklib::HugeSystem, FR>
            ABCH(qap,
                 m_witness,
                 m_randomness.d1(),
                 m_randomness.d2(),
                 m_randomness.d3());

        auto space = snarklib::BlockVector<FR>::space(ABCH.vec());
        space.blockPartition(std::array<size_t, 1>{m_numBlocks});

        if (! write_blockvector(outfile, space, ABCH.vec()))
            m_error = true;
    }

private:
    const std::size_t m_numBlocks;

    snarklib::R1Witness<FR> m_witness;
    snarklib::PPZK_ProofRandomness<FR> m_randomness;
    snarklib::HugeSystem<FR> m_hugeSystem;
    bool m_error;
};

} // namespace snarkfront

#endif
<|endoftext|>


<commit_before>/**
 * @file Connection.cpp
 * @brief
 * @author Travis Lane
 * @version 0.0.1
 * @date 2016-01-05
 */

#include "Connection.h"

Connection::Connection(Bluetooth &new_bt, int id) : bt(new_bt)
{
  this->id = id;
}

int Connection::write(int percent)
{
  int rc = 0;
  StaticJsonBuffer<200> buffer;
  JsonObject& object = buffer.createObject();

  if (!bt.connected()) {
    return -1;
  }

  object["id"] = this->id;
  object["throttle"] = percent;

  /* Don't pretty print, I deliminate on \n */
  rc = object.printTo(bt);
  bt.write('\n');

  return rc;
}

int Connection::read(int *out_percent)
{
  int rc = 0;
  char buff[200];
  StaticJsonBuffer<200> buffer;

  if (!bt.connected()) {
    return -1;
  }

  rc = bt.readBytesUntil('\n', buff, sizeof(buff));
  if (rc <= 0) {
    return -1;
  }

  /* Set last char to NULL */
  buff[rc] = '\0';

  JsonObject& object = buffer.parseObject(buff);

  if (!object.success()) {
    return -1;
  }

  if (object["id"] != id) {
    /* The ID doesn't match... We should ignore this message */
    return -1;
  }

  *out_percent = object["throttle"];
  return rc;
}
<commit_msg>Change status codes for debugging<commit_after>/**
 * @file Connection.cpp
 * @brief
 * @author Travis Lane
 * @version 0.0.1
 * @date 2016-01-05
 */

#include "Connection.h"

Connection::Connection(Bluetooth &new_bt, int id) : bt(new_bt)
{
  this->id = id;
}

int Connection::write(int percent)
{
  int rc = 0;
  StaticJsonBuffer<200> buffer;
  JsonObject& object = buffer.createObject();

  if (!bt.connected()) {
    return -1;
  }

  object["id"] = this->id;
  object["throttle"] = percent;

  /* Don't pretty print, I deliminate on \n */
  rc = object.printTo(bt);
  bt.write('\n');

  return rc;
}

int Connection::read(int *out_percent)
{
  int rc = 0;
  char buff[200];
  StaticJsonBuffer<200> buffer;

  if (!bt.connected()) {
    return -1;
  }

  rc = bt.readBytesUntil('\n', buff, sizeof(buff));
  if (rc <= 0) {
    return -2;
  }

  /* Set last char to NULL */
  buff[rc] = '\0';

  JsonObject& object = buffer.parseObject(buff);

  if (!object.success()) {
    return -3;
  }

  if (object["id"] != id) {
    /* The ID doesn't match... We should ignore this message */
    return -4;
  }

  *out_percent = object["throttle"];
  return rc;
}
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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.
//*****************************************************************************

#pragma once

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "ngraph/pass/manager.hpp"
#include "ngraph/runtime/executable.hpp"

namespace ngraph
{
    namespace runtime
    {
        class Backend;

        namespace hybrid
        {
            class HybridExecutable;
        }
    } // namespace runtime
} // namespace ngraph

class ngraph::runtime::hybrid::HybridExecutable : public runtime::Executable
{
public:
    HybridExecutable(const std::vector<std::shared_ptr<runtime::Backend>>& backend_list,
                     const std::shared_ptr<Function>& func,
                     bool enable_performance_collection = false,
                     bool debug_enabled = false);

    bool call(const std::vector<std::shared_ptr<ngraph::runtime::Tensor>>& outputs,
              const std::vector<std::shared_ptr<ngraph::runtime::Tensor>>& inputs) override;

    template <typename T>
    std::shared_ptr<T> get_as() const
    {
        return std::dynamic_pointer_cast<T>(m_executable);
    }

    /// Allow overriding the configuration of the pass manager. If you overload this method
    /// you must define all passes.
    virtual void configure_passes(ngraph::pass::Manager& pass_manager);

protected:
    std::shared_ptr<ngraph::Function> m_function;
    std::shared_ptr<Executable> m_executable;
    std::unordered_map<std::shared_ptr<ngraph::op::Parameter>, std::shared_ptr<ngraph::op::Result>>
        m_map_parameter_to_result;

    std::vector<std::shared_ptr<runtime::Backend>> m_backend_list;
    bool m_debug_enabled = false;
};
<commit_msg>Add check to hybridexecutable::get_as. (#2998)<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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.
//*****************************************************************************

#pragma once

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "ngraph/pass/manager.hpp"
#include "ngraph/runtime/executable.hpp"

namespace ngraph
{
    namespace runtime
    {
        class Backend;

        namespace hybrid
        {
            class HybridExecutable;
        }
    } // namespace runtime
} // namespace ngraph

class ngraph::runtime::hybrid::HybridExecutable : public runtime::Executable
{
public:
    HybridExecutable(const std::vector<std::shared_ptr<runtime::Backend>>& backend_list,
                     const std::shared_ptr<Function>& func,
                     bool enable_performance_collection = false,
                     bool debug_enabled = false);

    bool call(const std::vector<std::shared_ptr<ngraph::runtime::Tensor>>& outputs,
              const std::vector<std::shared_ptr<ngraph::runtime::Tensor>>& inputs) override;

    template <typename T>
    std::shared_ptr<T> get_as() const
    {
        if (auto exec = std::dynamic_pointer_cast<T>(m_executable))
        {
            return exec;
        }
        else
        {
            throw ngraph::ngraph_error("Requested invalid ngraph::Executable subclass");
        }
    }

    /// Allow overriding the configuration of the pass manager. If you overload this method
    /// you must define all passes.
    virtual void configure_passes(ngraph::pass::Manager& pass_manager);

protected:
    std::shared_ptr<ngraph::Function> m_function;
    std::shared_ptr<Executable> m_executable;
    std::unordered_map<std::shared_ptr<ngraph::op::Parameter>, std::shared_ptr<ngraph::op::Result>>
        m_map_parameter_to_result;

    std::vector<std::shared_ptr<runtime::Backend>> m_backend_list;
    bool m_debug_enabled = false;
};
<|endoftext|>