<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtGui/qgraphicsanchorlayout.h>
#include <QtGui/qgraphicslinearlayout.h>
#include <QtGui/qgraphicswidget.h>
#include <QtGui/qgraphicsview.h>

class tst_QGraphicsAnchorLayout : public QObject
{
    Q_OBJECT
public:
    tst_QGraphicsAnchorLayout() {}
    ~tst_QGraphicsAnchorLayout() {}

private slots:
    void s60_hard_complex_data();
    void s60_hard_complex();
    void linearVsAnchorNested_data();
    void linearVsAnchorNested();

};

class RectWidget : public QGraphicsWidget
{
public:
    RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option);
        Q_UNUSED(widget);
        painter->drawRoundRect(rect());
        painter->drawLine(rect().topLeft(), rect().bottomRight());
        painter->drawLine(rect().bottomLeft(), rect().topRight());
    }
};

static QGraphicsWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
                                   const QSizeF &preferred = QSize(150.0, 100.0),
                                   const QSizeF &maximum = QSizeF(200.0, 100.0),
                                   const QString &name = QString())
{
    QGraphicsWidget *w = new RectWidget;
    w->setMinimumSize(minimum);
    w->setPreferredSize(preferred);
    w->setMaximumSize(maximum);
    w->setData(0, name);
    return w;
}

static void setAnchor(QGraphicsAnchorLayout *l,
                      QGraphicsLayoutItem *firstItem,
                      Qt::AnchorPoint firstEdge,
                      QGraphicsLayoutItem *secondItem,
                      Qt::AnchorPoint secondEdge,
                      qreal spacing)
{
    QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
    anchor->setSpacing(spacing);
}

void tst_QGraphicsAnchorLayout::s60_hard_complex_data()
{
    QTest::addColumn<int>("whichSizeHint");
    QTest::newRow("minimumSizeHint")
        << int(Qt::MinimumSize);
    QTest::newRow("preferredSizeHint")
        << int(Qt::PreferredSize);
    QTest::newRow("maximumSizeHint")
        << int(Qt::MaximumSize);
    // Add it as a reference to see how much overhead the body of effectiveSizeHint takes.
    QTest::newRow("noSizeHint")
        << -1;
}

void tst_QGraphicsAnchorLayout::s60_hard_complex()
{
    QFETCH(int, whichSizeHint);

    // Test for "hard" complex case, taken from wiki
    // https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases
    QSizeF min(0, 10);
    QSizeF pref(50, 10);
    QSizeF max(100, 10);

    QGraphicsWidget *a = createItem(min, pref, max, "a");
    QGraphicsWidget *b = createItem(min, pref, max, "b");
    QGraphicsWidget *c = createItem(min, pref, max, "c");
    QGraphicsWidget *d = createItem(min, pref, max, "d");
    QGraphicsWidget *e = createItem(min, pref, max, "e");
    QGraphicsWidget *f = createItem(min, pref, max, "f");
    QGraphicsWidget *g = createItem(min, pref, max, "g");

    QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
    l->setContentsMargins(0, 0, 0, 0);

    //<!-- Trunk -->
    setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 10);
    setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 10);
    setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 10);
    setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
    setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 10);

    //<!-- Above trunk -->
    setAnchor(l, b, Qt::AnchorLeft, e, Qt::AnchorLeft, 10);
    setAnchor(l, e, Qt::AnchorRight, d, Qt::AnchorLeft, 10);

    //<!-- Below trunk -->
    setAnchor(l, a, Qt::AnchorHorizontalCenter, g, Qt::AnchorLeft, 10);
    setAnchor(l, g, Qt::AnchorRight, f, Qt::AnchorHorizontalCenter, 10);
    setAnchor(l, c, Qt::AnchorLeft, f, Qt::AnchorLeft, 10);
    setAnchor(l, f, Qt::AnchorRight, d, Qt::AnchorRight, 10);

    //<!-- vertical is simpler -->
    setAnchor(l, l, Qt::AnchorTop, e, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, a, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, b, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, d, Qt::AnchorTop, 0);
    setAnchor(l, a, Qt::AnchorBottom, f, Qt::AnchorTop, 0);
    setAnchor(l, a, Qt::AnchorBottom, b, Qt::AnchorBottom, 0);
    setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorBottom, 0);
    setAnchor(l, a, Qt::AnchorBottom, d, Qt::AnchorBottom, 0);
    setAnchor(l, f, Qt::AnchorBottom, g, Qt::AnchorTop, 0);
    setAnchor(l, g, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);

    // It won't query the size hint if it already has a size set.
    // If only one of the sizes is unset it will query sizeHint only of for that hint type.
    l->setMinimumSize(60,40);
    l->setPreferredSize(220,40);
    l->setMaximumSize(240,40);

    switch (whichSizeHint) {
    case Qt::MinimumSize:
        l->setMinimumSize(-1, -1);
        break;
    case Qt::PreferredSize:
        l->setPreferredSize(-1, -1);
        break;
    case Qt::MaximumSize:
        l->setMaximumSize(-1, -1);
        break;
    default:
        break;
    }

    QSizeF sizeHint;
    // warm up instruction cache
    l->invalidate();
    sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    // ...then measure...
    QBENCHMARK {
        l->invalidate();
        sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    }
}

void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data()
{
    QTest::addColumn<int>("whichLayout");
    QTest::newRow("LinearLayout")
        << 0;
    QTest::newRow("AnchorLayout setup with null-anchors knot")
        << 1;
    QTest::newRow("AnchorLayout setup easy to simplificate")
        << 2;
}

void tst_QGraphicsAnchorLayout::linearVsAnchorNested()
{
    QFETCH(int, whichLayout);

    QSizeF min(10, 10);
    QSizeF pref(80, 80);
    QSizeF max(150, 150);

    QGraphicsWidget *a = createItem(min, pref, max, "a");
    QGraphicsWidget *b = createItem(min, pref, max, "b");
    QGraphicsWidget *c = createItem(min, pref, max, "c");
    QGraphicsWidget *d = createItem(min, pref, max, "d");

    QGraphicsLayout *layout;

    if (whichLayout == 0) {
        QGraphicsLinearLayout *linear1 = new QGraphicsLinearLayout;
        QGraphicsLinearLayout *linear2 = new QGraphicsLinearLayout(Qt::Vertical);
        QGraphicsLinearLayout *linear3 = new QGraphicsLinearLayout;

        linear1->addItem(a);
        linear1->addItem(linear2);
        linear2->addItem(b);
        linear2->addItem(linear3);
        linear3->addItem(c);
        linear3->addItem(d);

        layout = linear1;
    } else if (whichLayout == 1) {
        QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;

        // A
        anchor->addCornerAnchors(a, Qt::TopLeftCorner, anchor, Qt::TopLeftCorner);
        anchor->addCornerAnchors(a, Qt::TopRightCorner, b, Qt::TopLeftCorner);
        anchor->addCornerAnchors(a, Qt::BottomLeftCorner, anchor, Qt::BottomLeftCorner);
        anchor->addCornerAnchors(a, Qt::BottomRightCorner, c, Qt::BottomLeftCorner);

        // B
        anchor->addCornerAnchors(b, Qt::TopRightCorner, anchor, Qt::TopRightCorner);
        anchor->addCornerAnchors(b, Qt::BottomLeftCorner, c, Qt::TopLeftCorner);
        anchor->addCornerAnchors(b, Qt::BottomRightCorner, d, Qt::TopRightCorner);

        // C
        anchor->addCornerAnchors(c, Qt::TopRightCorner, d, Qt::TopLeftCorner);
        anchor->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::BottomLeftCorner);

        // D
        anchor->addCornerAnchors(d, Qt::BottomRightCorner, anchor, Qt::BottomRightCorner);

        layout = anchor;
    } else {
        QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;

        // A
        anchor->addAnchor(a, Qt::AnchorLeft, anchor, Qt::AnchorLeft);
        anchor->addAnchors(a, anchor, Qt::Vertical);
        anchor->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
        anchor->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);

        // B
        anchor->addAnchor(b, Qt::AnchorTop, anchor, Qt::AnchorTop);
        anchor->addAnchor(b, Qt::AnchorRight, anchor, Qt::AnchorRight);
        anchor->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
        anchor->addAnchor(b, Qt::AnchorBottom, d, Qt::AnchorTop);

        // C
        anchor->addAnchor(c, Qt::AnchorRight, d, Qt::AnchorLeft);
        anchor->addAnchor(c, Qt::AnchorBottom, anchor, Qt::AnchorBottom);

        // D
        anchor->addAnchor(d, Qt::AnchorRight, anchor, Qt::AnchorRight);
        anchor->addAnchor(d, Qt::AnchorBottom, anchor, Qt::AnchorBottom);

        layout = anchor;
    }

    QSizeF sizeHint;
    // warm up instruction cache
    layout->invalidate();
    sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);

    // ...then measure...
    QBENCHMARK {
        // To ensure that all sizeHints caches are invalidated in
        // the LinearLayout setup, we must call updateGeometry on the
        // children. If we didn't, only the top level layout would be
        // re-calculated.
        static_cast<QGraphicsLayoutItem *>(a)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(b)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(c)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(d)->updateGeometry();
        layout->invalidate();
        sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);
    }
}

QTEST_MAIN(tst_QGraphicsAnchorLayout)

#include "tst_qgraphicsanchorlayout.moc"
<commit_msg>QGraphicsAnchorLayout: Adding two benchmarks on LinearLayout vs AnchorLayout cases<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtGui/qgraphicsanchorlayout.h>
#include <QtGui/qgraphicslinearlayout.h>
#include <QtGui/qgraphicswidget.h>
#include <QtGui/qgraphicsview.h>

class tst_QGraphicsAnchorLayout : public QObject
{
    Q_OBJECT
public:
    tst_QGraphicsAnchorLayout() {}
    ~tst_QGraphicsAnchorLayout() {}

private slots:
    void s60_hard_complex_data();
    void s60_hard_complex();
    void linearVsAnchorSizeHints_data();
    void linearVsAnchorSizeHints();
    void linearVsAnchorSetGeometry_data();
    void linearVsAnchorSetGeometry();
    void linearVsAnchorNested_data();
    void linearVsAnchorNested();
};

class RectWidget : public QGraphicsWidget
{
public:
    RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option);
        Q_UNUSED(widget);
        painter->drawRoundRect(rect());
        painter->drawLine(rect().topLeft(), rect().bottomRight());
        painter->drawLine(rect().bottomLeft(), rect().topRight());
    }
};

static QGraphicsWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
                                   const QSizeF &preferred = QSize(150.0, 100.0),
                                   const QSizeF &maximum = QSizeF(200.0, 100.0),
                                   const QString &name = QString())
{
    QGraphicsWidget *w = new RectWidget;
    w->setMinimumSize(minimum);
    w->setPreferredSize(preferred);
    w->setMaximumSize(maximum);
    w->setData(0, name);
    return w;
}

static void setAnchor(QGraphicsAnchorLayout *l,
                      QGraphicsLayoutItem *firstItem,
                      Qt::AnchorPoint firstEdge,
                      QGraphicsLayoutItem *secondItem,
                      Qt::AnchorPoint secondEdge,
                      qreal spacing)
{
    QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
    anchor->setSpacing(spacing);
}

void tst_QGraphicsAnchorLayout::s60_hard_complex_data()
{
    QTest::addColumn<int>("whichSizeHint");
    QTest::newRow("minimumSizeHint")
        << int(Qt::MinimumSize);
    QTest::newRow("preferredSizeHint")
        << int(Qt::PreferredSize);
    QTest::newRow("maximumSizeHint")
        << int(Qt::MaximumSize);
    // Add it as a reference to see how much overhead the body of effectiveSizeHint takes.
    QTest::newRow("noSizeHint")
        << -1;
}

void tst_QGraphicsAnchorLayout::s60_hard_complex()
{
    QFETCH(int, whichSizeHint);

    // Test for "hard" complex case, taken from wiki
    // https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases
    QSizeF min(0, 10);
    QSizeF pref(50, 10);
    QSizeF max(100, 10);

    QGraphicsWidget *a = createItem(min, pref, max, "a");
    QGraphicsWidget *b = createItem(min, pref, max, "b");
    QGraphicsWidget *c = createItem(min, pref, max, "c");
    QGraphicsWidget *d = createItem(min, pref, max, "d");
    QGraphicsWidget *e = createItem(min, pref, max, "e");
    QGraphicsWidget *f = createItem(min, pref, max, "f");
    QGraphicsWidget *g = createItem(min, pref, max, "g");

    QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
    l->setContentsMargins(0, 0, 0, 0);

    //<!-- Trunk -->
    setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 10);
    setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 10);
    setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 10);
    setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
    setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 10);

    //<!-- Above trunk -->
    setAnchor(l, b, Qt::AnchorLeft, e, Qt::AnchorLeft, 10);
    setAnchor(l, e, Qt::AnchorRight, d, Qt::AnchorLeft, 10);

    //<!-- Below trunk -->
    setAnchor(l, a, Qt::AnchorHorizontalCenter, g, Qt::AnchorLeft, 10);
    setAnchor(l, g, Qt::AnchorRight, f, Qt::AnchorHorizontalCenter, 10);
    setAnchor(l, c, Qt::AnchorLeft, f, Qt::AnchorLeft, 10);
    setAnchor(l, f, Qt::AnchorRight, d, Qt::AnchorRight, 10);

    //<!-- vertical is simpler -->
    setAnchor(l, l, Qt::AnchorTop, e, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, a, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, b, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
    setAnchor(l, e, Qt::AnchorBottom, d, Qt::AnchorTop, 0);
    setAnchor(l, a, Qt::AnchorBottom, f, Qt::AnchorTop, 0);
    setAnchor(l, a, Qt::AnchorBottom, b, Qt::AnchorBottom, 0);
    setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorBottom, 0);
    setAnchor(l, a, Qt::AnchorBottom, d, Qt::AnchorBottom, 0);
    setAnchor(l, f, Qt::AnchorBottom, g, Qt::AnchorTop, 0);
    setAnchor(l, g, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);

    // It won't query the size hint if it already has a size set.
    // If only one of the sizes is unset it will query sizeHint only of for that hint type.
    l->setMinimumSize(60,40);
    l->setPreferredSize(220,40);
    l->setMaximumSize(240,40);

    switch (whichSizeHint) {
    case Qt::MinimumSize:
        l->setMinimumSize(-1, -1);
        break;
    case Qt::PreferredSize:
        l->setPreferredSize(-1, -1);
        break;
    case Qt::MaximumSize:
        l->setMaximumSize(-1, -1);
        break;
    default:
        break;
    }

    QSizeF sizeHint;
    // warm up instruction cache
    l->invalidate();
    sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    // ...then measure...
    QBENCHMARK {
        l->invalidate();
        sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    }
}

static QGraphicsLayout* createLayouts(int whichLayout)
{
    QSizeF min(0, 10);
    QSizeF pref(50, 10);
    QSizeF max(100, 10);

    QGraphicsWidget *a = createItem(min, pref, max, "a");
    QGraphicsWidget *b = createItem(min, pref, max, "b");
    QGraphicsWidget *c = createItem(min, pref, max, "c");
    QGraphicsWidget *d = createItem(min, pref, max, "d");

    QGraphicsLayout *l;
    if (whichLayout == 0) {
        l = new QGraphicsLinearLayout;
        QGraphicsLinearLayout *linear = static_cast<QGraphicsLinearLayout *>(l);
        linear->setContentsMargins(0, 0, 0, 0);

        linear->addItem(a);
        linear->addItem(b);
        linear->addItem(c);
        linear->addItem(d);
    } else {
        l = new QGraphicsAnchorLayout;
        QGraphicsAnchorLayout *anchor = static_cast<QGraphicsAnchorLayout *>(l);
        anchor->setContentsMargins(0, 0, 0, 0);

        // Horizontal
        setAnchor(anchor, anchor, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
        setAnchor(anchor, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0);
        setAnchor(anchor, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0);
        setAnchor(anchor, c, Qt::AnchorRight, d, Qt::AnchorLeft, 0);
        setAnchor(anchor, d, Qt::AnchorRight, anchor, Qt::AnchorRight, 0);

        // Vertical
        anchor->addAnchors(anchor, a, Qt::Vertical);
        anchor->addAnchors(anchor, b, Qt::Vertical);
        anchor->addAnchors(anchor, c, Qt::Vertical);
        anchor->addAnchors(anchor, d, Qt::Vertical);
    }

    return l;
}

void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints_data()
{
    QTest::addColumn<int>("whichLayout");
    QTest::addColumn<int>("whichSizeHint");

    QTest::newRow("QGraphicsLinearLayout::minimum")
        << 0 << int(Qt::MinimumSize);
    QTest::newRow("QGraphicsLinearLayout::preferred")
        << 0 << int(Qt::PreferredSize);
    QTest::newRow("QGraphicsLinearLayout::maximum")
        << 0 << int(Qt::MaximumSize);
    QTest::newRow("QGraphicsLinearLayout::noSizeHint")
        << 0 << -1;

    QTest::newRow("QGraphicsAnchorLayout::minimum")
        << 1 << int(Qt::MinimumSize);
    QTest::newRow("QGraphicsAnchorLayout::preferred")
        << 1 << int(Qt::PreferredSize);
    QTest::newRow("QGraphicsAnchorLayout::maximum")
        << 1 << int(Qt::MaximumSize);
    QTest::newRow("QGraphicsAnchorLayout::noSizeHint")
        << 1 << -1;
}

void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints()
{
    QFETCH(int, whichSizeHint);
    QFETCH(int, whichLayout);

    QGraphicsLayout *l = createLayouts(whichLayout);

    QSizeF sizeHint;
    // warm up instruction cache
    l->invalidate();
    sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    // ...then measure...

    QBENCHMARK {
        l->invalidate();
        sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
    }
}

void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry_data()
{
    QTest::addColumn<int>("whichLayout");

    QTest::newRow("QGraphicsLinearLayout")
        << 0;
    QTest::newRow("QGraphicsAnchorLayout")
        << 1;
}

void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry()
{
    QFETCH(int, whichLayout);

    QGraphicsLayout *l = createLayouts(whichLayout);

    QRectF sizeHint;
    qreal maxWidth;
    qreal increment;
    // warm up instruction cache
    l->invalidate();
    sizeHint.setSize(l->effectiveSizeHint(Qt::MinimumSize));
    maxWidth = l->effectiveSizeHint(Qt::MaximumSize).width();
    increment = (maxWidth - sizeHint.width()) / 100;
    l->setGeometry(sizeHint);
    // ...then measure...

    QBENCHMARK {
        l->invalidate();
        for (qreal width = sizeHint.width(); width <= maxWidth; width += increment) {
            sizeHint.setWidth(width);
            l->setGeometry(sizeHint);
        }
    }
}

void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data()
{
    QTest::addColumn<int>("whichLayout");
    QTest::newRow("LinearLayout")
        << 0;
    QTest::newRow("AnchorLayout setup with null-anchors knot")
        << 1;
    QTest::newRow("AnchorLayout setup easy to simplificate")
        << 2;
}

void tst_QGraphicsAnchorLayout::linearVsAnchorNested()
{
    QFETCH(int, whichLayout);

    QSizeF min(10, 10);
    QSizeF pref(80, 80);
    QSizeF max(150, 150);

    QGraphicsWidget *a = createItem(min, pref, max, "a");
    QGraphicsWidget *b = createItem(min, pref, max, "b");
    QGraphicsWidget *c = createItem(min, pref, max, "c");
    QGraphicsWidget *d = createItem(min, pref, max, "d");

    QGraphicsLayout *layout;

    if (whichLayout == 0) {
        QGraphicsLinearLayout *linear1 = new QGraphicsLinearLayout;
        QGraphicsLinearLayout *linear2 = new QGraphicsLinearLayout(Qt::Vertical);
        QGraphicsLinearLayout *linear3 = new QGraphicsLinearLayout;

        linear1->addItem(a);
        linear1->addItem(linear2);
        linear2->addItem(b);
        linear2->addItem(linear3);
        linear3->addItem(c);
        linear3->addItem(d);

        layout = linear1;
    } else if (whichLayout == 1) {
        QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;

        // A
        anchor->addCornerAnchors(a, Qt::TopLeftCorner, anchor, Qt::TopLeftCorner);
        anchor->addCornerAnchors(a, Qt::TopRightCorner, b, Qt::TopLeftCorner);
        anchor->addCornerAnchors(a, Qt::BottomLeftCorner, anchor, Qt::BottomLeftCorner);
        anchor->addCornerAnchors(a, Qt::BottomRightCorner, c, Qt::BottomLeftCorner);

        // B
        anchor->addCornerAnchors(b, Qt::TopRightCorner, anchor, Qt::TopRightCorner);
        anchor->addCornerAnchors(b, Qt::BottomLeftCorner, c, Qt::TopLeftCorner);
        anchor->addCornerAnchors(b, Qt::BottomRightCorner, d, Qt::TopRightCorner);

        // C
        anchor->addCornerAnchors(c, Qt::TopRightCorner, d, Qt::TopLeftCorner);
        anchor->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::BottomLeftCorner);

        // D
        anchor->addCornerAnchors(d, Qt::BottomRightCorner, anchor, Qt::BottomRightCorner);

        layout = anchor;
    } else {
        QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;

        // A
        anchor->addAnchor(a, Qt::AnchorLeft, anchor, Qt::AnchorLeft);
        anchor->addAnchors(a, anchor, Qt::Vertical);
        anchor->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
        anchor->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);

        // B
        anchor->addAnchor(b, Qt::AnchorTop, anchor, Qt::AnchorTop);
        anchor->addAnchor(b, Qt::AnchorRight, anchor, Qt::AnchorRight);
        anchor->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
        anchor->addAnchor(b, Qt::AnchorBottom, d, Qt::AnchorTop);

        // C
        anchor->addAnchor(c, Qt::AnchorRight, d, Qt::AnchorLeft);
        anchor->addAnchor(c, Qt::AnchorBottom, anchor, Qt::AnchorBottom);

        // D
        anchor->addAnchor(d, Qt::AnchorRight, anchor, Qt::AnchorRight);
        anchor->addAnchor(d, Qt::AnchorBottom, anchor, Qt::AnchorBottom);

        layout = anchor;
    }

    QSizeF sizeHint;
    // warm up instruction cache
    layout->invalidate();
    sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);

    // ...then measure...
    QBENCHMARK {
        // To ensure that all sizeHints caches are invalidated in
        // the LinearLayout setup, we must call updateGeometry on the
        // children. If we didn't, only the top level layout would be
        // re-calculated.
        static_cast<QGraphicsLayoutItem *>(a)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(b)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(c)->updateGeometry();
        static_cast<QGraphicsLayoutItem *>(d)->updateGeometry();
        layout->invalidate();
        sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);
    }
}

QTEST_MAIN(tst_QGraphicsAnchorLayout)

#include "tst_qgraphicsanchorlayout.moc"
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "third_party/googletest/src/include/gtest/gtest.h"

#include "test/ivf_video_source.h"
#include "./vpx_config.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"

namespace {

#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))

TEST(DecodeAPI, InvalidParams) {
  static const vpx_codec_iface_t *kCodecs[] = {
#if CONFIG_VP8_DECODER
    &vpx_codec_vp8_dx_algo,
#endif
#if CONFIG_VP9_DECODER
    &vpx_codec_vp9_dx_algo,
#endif
  };
  uint8_t buf[1] = {0};
  vpx_codec_ctx_t dec;

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(NULL, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(&dec, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, NULL, 0, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, buf, 0, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_decode(NULL, buf, NELEMENTS(buf), NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_decode(NULL, NULL, NELEMENTS(buf), NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
  EXPECT_TRUE(vpx_codec_error(NULL) != NULL);

  for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_dec_init(NULL, kCodecs[i], NULL, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
              vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_decode(&dec, buf, 0, NULL, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
  }
}

#if CONFIG_VP9_DECODER
// Test VP9 codec controls after a decode error to ensure the code doesn't
// misbehave.
void TestVp9Controls(vpx_codec_ctx_t *dec) {
  static const int kControls[] = {
    VP8D_GET_LAST_REF_UPDATES,
    VP8D_GET_FRAME_CORRUPTED,
    VP9D_GET_DISPLAY_SIZE,
  };
  int val[2];

  for (int i = 0; i < NELEMENTS(kControls); ++i) {
    const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
    switch (kControls[i]) {
      case VP8D_GET_FRAME_CORRUPTED:
        EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
        break;
      default:
        EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
        break;
    }
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_control_(dec, kControls[i], NULL));
  }

  vp9_ref_frame_t ref;
  ref.idx = 0;
  EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));

  vpx_ref_frame_t ref_copy;
  const int width = 352;
  const int height = 288;
  ASSERT_TRUE(
      vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
  ref_copy.frame_type = VP8_LAST_FRAME;
  EXPECT_EQ(VPX_CODEC_ERROR,
            vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
  vpx_img_free(&ref_copy.img);
}

TEST(DecodeAPI, Vp9InvalidDecode) {
  const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
  const char filename[] =
      "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
  libvpx_test::IVFVideoSource video(filename);
  video.Init();
  video.Begin();
  ASSERT_TRUE(!HasFailure());

  vpx_codec_ctx_t dec;
  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
  const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
  EXPECT_EQ(VPX_CODEC_MEM_ERROR,
            vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
  vpx_codec_iter_t iter = NULL;
  EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));

  TestVp9Controls(&dec);
  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
#endif  // CONFIG_VP9_DECODER

}  // namespace
<commit_msg>Ensure the error-concealment code is available<commit_after>/*
 *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "third_party/googletest/src/include/gtest/gtest.h"

#include "test/ivf_video_source.h"
#include "./vpx_config.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"

namespace {

#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))

TEST(DecodeAPI, InvalidParams) {
  static const vpx_codec_iface_t *kCodecs[] = {
#if CONFIG_VP8_DECODER
    &vpx_codec_vp8_dx_algo,
#endif
#if CONFIG_VP9_DECODER
    &vpx_codec_vp9_dx_algo,
#endif
  };
  uint8_t buf[1] = {0};
  vpx_codec_ctx_t dec;

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(NULL, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(&dec, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, NULL, 0, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, buf, 0, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_decode(NULL, buf, NELEMENTS(buf), NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_decode(NULL, NULL, NELEMENTS(buf), NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
  EXPECT_TRUE(vpx_codec_error(NULL) != NULL);

  for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_dec_init(NULL, kCodecs[i], NULL, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
              vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_decode(&dec, buf, 0, NULL, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
  }
}

#if CONFIG_VP8_DECODER
TEST(DecodeAPI, OptionalParams) {
  vpx_codec_ctx_t dec;

#if CONFIG_ERROR_CONCEALMENT
  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
                                             VPX_CODEC_USE_ERROR_CONCEALMENT));
#else
  EXPECT_EQ(VPX_CODEC_INCAPABLE,
            vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
                               VPX_CODEC_USE_ERROR_CONCEALMENT));
#endif  // CONFIG_ERROR_CONCEALMENT
}
#endif  // CONFIG_VP8_DECODER

#if CONFIG_VP9_DECODER
// Test VP9 codec controls after a decode error to ensure the code doesn't
// misbehave.
void TestVp9Controls(vpx_codec_ctx_t *dec) {
  static const int kControls[] = {
    VP8D_GET_LAST_REF_UPDATES,
    VP8D_GET_FRAME_CORRUPTED,
    VP9D_GET_DISPLAY_SIZE,
  };
  int val[2];

  for (int i = 0; i < NELEMENTS(kControls); ++i) {
    const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
    switch (kControls[i]) {
      case VP8D_GET_FRAME_CORRUPTED:
        EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
        break;
      default:
        EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
        break;
    }
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_control_(dec, kControls[i], NULL));
  }

  vp9_ref_frame_t ref;
  ref.idx = 0;
  EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));

  vpx_ref_frame_t ref_copy;
  const int width = 352;
  const int height = 288;
  ASSERT_TRUE(
      vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
  ref_copy.frame_type = VP8_LAST_FRAME;
  EXPECT_EQ(VPX_CODEC_ERROR,
            vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
  vpx_img_free(&ref_copy.img);
}

TEST(DecodeAPI, Vp9InvalidDecode) {
  const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
  const char filename[] =
      "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
  libvpx_test::IVFVideoSource video(filename);
  video.Init();
  video.Begin();
  ASSERT_TRUE(!HasFailure());

  vpx_codec_ctx_t dec;
  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
  const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
  EXPECT_EQ(VPX_CODEC_MEM_ERROR,
            vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
  vpx_codec_iter_t iter = NULL;
  EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));

  TestVp9Controls(&dec);
  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
#endif  // CONFIG_VP9_DECODER

}  // namespace
<|endoftext|>


<commit_before>#include <curl/curl.h>
#include <cstdlib>
#include <cstring>
#include "datafeed.h"
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
#include "vote.h"
#include "main.h"
#include "bitcoinrpc.h"
#include "wallet.h"

using namespace std;
using namespace json_spirit;

string strDataFeedError = "";

class DataFeedRequest
{
private:
    CURL *curl;
    string result;
    string error;
    string url;

    size_t ReceiveCallback(char *contents, size_t size, size_t nmemb)
    {
        if (size == 0 || nmemb == 0)
            return 0;

        size_t written = 0;

        try
        {
            size_t realsize = size * nmemb;

            int nMaxSize = GetArg("maxdatafeedsize", 10 * 1024);
            if (result.size() + realsize > nMaxSize)
                throw runtime_error((boost::format("Data feed size exceeds limit (%1% bytes)") % nMaxSize).str());

            result.append(contents, realsize);
            written = realsize;
        }
        catch (exception &e)
        {
            error = string(e.what());
        }

        return written;
    }

    static size_t WriteMemoryCallback(char *contents, size_t size, size_t nmemb, void *userp)
    {
        DataFeedRequest *request = (DataFeedRequest*)userp;
        return request->ReceiveCallback(contents, size, nmemb);
    }

public:
    DataFeedRequest(const string& sURL)
        : url(sURL)
    {
        curl = curl_easy_init();
        if (curl == NULL)
            throw runtime_error("Failed to initialize curl");

        curl_easy_setopt(curl, CURLOPT_URL, sURL.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)this);

        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);

        if (fUseProxy)
        {
            curl_easy_setopt(curl, CURLOPT_PROXY, addrProxy.ToStringIP().c_str());
            curl_easy_setopt(curl, CURLOPT_PROXYPORT, addrProxy.GetPort());
            curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
        }
    }

    ~DataFeedRequest()
    {
        if (curl)
        {
            curl_easy_cleanup(curl);
            curl = NULL;
        }
    }

    void Perform()
    {
        CURLcode res;
        res = curl_easy_perform(curl);

        if (res == CURLE_OK)
        {
            long http_code = 0;
            if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code) != CURLE_OK)
                throw runtime_error("Unable to get data feed response code");

            if (http_code != 200)
                throw runtime_error((boost::format("Data feed failed: Response code %ld") % http_code).str());

            printf("Received %lu bytes from data feed %s:\n%s\n", (long)result.size(), url.c_str(), result.c_str());
        }
        else
        {
            if (error == "")
            {
                error = (boost::format("Data feed failed: %s") % curl_easy_strerror(res)).str();
                throw runtime_error(error);
            }
            else
                throw runtime_error(error);
        }
    }

    string GetResult() const
    {
        return result;
    }
};

void VerifyDataFeedSignature(const string& strMessage, const string& strSign, const string& strAddress)
{
    CBitcoinAddress addr(strAddress);
    if (!addr.IsValid())
        throw runtime_error("Invalid data feed address");

    CKeyID keyID;
    if (!addr.GetKeyID(keyID))
        throw runtime_error("Data feed address does not refer to key");

    bool fInvalid = false;
    vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);

    if (fInvalid)
        throw runtime_error("Malformed base64 encoding of data feed signature");

    CDataStream ss(SER_GETHASH, 0);
    ss << strMessageMagic;
    ss << strMessage;

    CKey key;
    if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
        throw runtime_error("Unable to set key from data feed signature");

    if (key.GetPubKey().GetID() != keyID)
        throw runtime_error("Data feed signature check failed");
}

bool GetVoteFromDataFeed(const CDataFeed& dataFeed, CVote& voteRet)
{
    bool result = false;

    try
    {
        DataFeedRequest request(dataFeed.sURL);
        request.Perform();

        if (dataFeed.sSignatureAddress != "" && dataFeed.sSignatureURL != "")
        {
            DataFeedRequest signatureRequest(dataFeed.sSignatureURL);
            signatureRequest.Perform();

            VerifyDataFeedSignature(request.GetResult(), signatureRequest.GetResult(), dataFeed.sSignatureAddress);
        }

        Value valReply;
        if (!read_string(request.GetResult(), valReply))
            throw runtime_error("Data feed returned invalid data");

        voteRet = ParseVote(valReply.get_obj());
        result = true;
    }
    catch (exception &e)
    {
        printf("GetVoteFromDataFeed error: %s\n", e.what());
        throw;
    }

    return result;
}

CVote ParseVote(const Object& objVote)
{
    CVote vote;

    BOOST_FOREACH(const Pair& voteAttribute, objVote)
    {
        if (voteAttribute.name_ == "motions")
        {
            BOOST_FOREACH(const Value& motionVoteObject, voteAttribute.value_.get_array())
                vote.vMotion.push_back(uint160(motionVoteObject.get_str()));
        }
        else if (voteAttribute.name_ == "custodians")
        {
            BOOST_FOREACH(const Value& custodianVoteObject, voteAttribute.value_.get_array())
            {
                CCustodianVote custodianVote;
                BOOST_FOREACH(const Pair& custodianVoteAttribute, custodianVoteObject.get_obj())
                {
                    if (custodianVoteAttribute.name_ == "address")
                    {
                        CBitcoinAddress address(custodianVoteAttribute.value_.get_str());
                        if (!address.IsValid())
                            throw runtime_error("Invalid address\n");

                        custodianVote.SetAddress(address);
                        if (custodianVote.cUnit == 'S' || !ValidUnit(custodianVote.cUnit))
                            throw runtime_error("Invalid custodian unit\n");
                    }
                    else if (custodianVoteAttribute.name_ == "amount")
                        custodianVote.nAmount = AmountFromValue(custodianVoteAttribute.value_);
                    else
                        throw runtime_error("Invalid custodian vote object\n");
                }
                vote.vCustodianVote.push_back(custodianVote);
            }
        }
        else if (voteAttribute.name_ == "parkrates")
        {
            BOOST_FOREACH(const Value& parkRateVoteObject, voteAttribute.value_.get_array())
            {
                CParkRateVote parkRateVote;
                BOOST_FOREACH(const Pair& parkRateVoteAttribute, parkRateVoteObject.get_obj())
                {
                    if (parkRateVoteAttribute.name_ == "unit")
                    {
                        parkRateVote.cUnit = parkRateVoteAttribute.value_.get_str()[0];
                        if (parkRateVote.cUnit == 'S' || !ValidUnit(parkRateVote.cUnit))
                            throw runtime_error("Invalid park rate unit\n");
                    }
                    else if (parkRateVoteAttribute.name_ == "rates")
                    {
                        BOOST_FOREACH(const Value& parkRateObject, parkRateVoteAttribute.value_.get_array())
                        {
                            CParkRate parkRate;
                            BOOST_FOREACH(const Pair& parkRateAttribute, parkRateObject.get_obj())
                            {
                                if (parkRateAttribute.name_ == "blocks")
                                {
                                   int blocks = parkRateAttribute.value_.get_int();
                                   double compactDuration = log2(blocks);
                                   double integerPart;
                                   if (modf(compactDuration, &integerPart) != 0.0)
                                       throw runtime_error("Park duration is not a power of 2\n");
                                   if (compactDuration < 0 || compactDuration > 255)
                                       throw runtime_error("Park duration out of range\n");
                                   parkRate.nCompactDuration = compactDuration;
                                }
                                else if (parkRateAttribute.name_ == "rate")
                                {
                                    double dAmount = parkRateAttribute.value_.get_real();
                                    if (dAmount < 0.0 || dAmount > MAX_MONEY)
                                        throw runtime_error("Invalid park rate amount\n");
                                    parkRate.nRate = roundint64(dAmount * COIN_PARK_RATE);
                                    if (!MoneyRange(parkRate.nRate))
                                        throw runtime_error("Invalid park rate amount\n");
                                }
                                else
                                    throw runtime_error("Invalid park rate object\n");
                            }
                            parkRateVote.vParkRate.push_back(parkRate);
                        }
                    }
                    else
                        throw runtime_error("Invalid custodian vote object\n");
                }
                vote.vParkRateVote.push_back(parkRateVote);
            }
        }
        else
            throw runtime_error("Invalid vote object\n");
    }

    return vote;
}

void UpdateFromDataFeed()
{
    CWallet* pwallet = GetWallet('S');
    CDataFeed dataFeed;
    {
        LOCK(pwallet->cs_wallet);
        dataFeed = pwallet->GetDataFeed();
    }

    if (dataFeed.sURL == "")
        return;

    printf("Updating from data feed %s\n", dataFeed.sURL.c_str());

    CVote feedVote;
    if (GetVoteFromDataFeed(dataFeed, feedVote))
    {
        LOCK(pwallet->cs_wallet);
        CVote newVote = pwallet->vote;
        BOOST_FOREACH(const string& sPart, dataFeed.vParts)
        {
            if (sPart == "custodians")
                newVote.vCustodianVote = feedVote.vCustodianVote;
            else if (sPart == "parkrates")
                newVote.vParkRateVote = feedVote.vParkRateVote;
            else if (sPart == "motions")
                newVote.vMotion = feedVote.vMotion;
            else
                throw runtime_error("Invalid part");
        }
        pwallet->SetVote(newVote);
        printf("Vote updated from data feed\n");
    }
}

void ThreadUpdateFromDataFeed(void* parg)
{
    printf("ThreadUpdateFromDataFeed started\n");

    int delay = GetArg("-datafeeddelay", 60);
    int64 lastUpdate = GetTime();

    while (true)
    {
#ifdef TESTING
        Sleep(200);
#else
        Sleep(1000);
#endif

        if (fShutdown)
            break;

        int64 now = GetTime();

        if (now >= lastUpdate + delay)
        {
            strDataFeedError = "";
            try
            {
                UpdateFromDataFeed();
            }
            catch (exception &e)
            {
                printf("UpdateFromDataFeed failed: %s\n", e.what());
                strDataFeedError = string(e.what());
            }

            lastUpdate = now;
        }
    }

    printf("ThreadUpdateFromDataFeed exited\n");
}

void StartUpdateFromDataFeed()
{
    if (!CreateThread(ThreadUpdateFromDataFeed, NULL))
        printf("Error; CreateThread(ThreadUpdateFromDataFeed) failed\n");
}
<commit_msg>Removed duplicate code<commit_after>#include <curl/curl.h>
#include <cstdlib>
#include <cstring>
#include "datafeed.h"
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
#include "vote.h"
#include "main.h"
#include "bitcoinrpc.h"
#include "wallet.h"

using namespace std;
using namespace json_spirit;

string strDataFeedError = "";

class DataFeedRequest
{
private:
    CURL *curl;
    string result;
    string error;
    string url;

    size_t ReceiveCallback(char *contents, size_t size, size_t nmemb)
    {
        if (size == 0 || nmemb == 0)
            return 0;

        size_t written = 0;

        try
        {
            size_t realsize = size * nmemb;

            int nMaxSize = GetArg("maxdatafeedsize", 10 * 1024);
            if (result.size() + realsize > nMaxSize)
                throw runtime_error((boost::format("Data feed size exceeds limit (%1% bytes)") % nMaxSize).str());

            result.append(contents, realsize);
            written = realsize;
        }
        catch (exception &e)
        {
            error = string(e.what());
        }

        return written;
    }

    static size_t WriteMemoryCallback(char *contents, size_t size, size_t nmemb, void *userp)
    {
        DataFeedRequest *request = (DataFeedRequest*)userp;
        return request->ReceiveCallback(contents, size, nmemb);
    }

public:
    DataFeedRequest(const string& sURL)
        : url(sURL)
    {
        curl = curl_easy_init();
        if (curl == NULL)
            throw runtime_error("Failed to initialize curl");

        curl_easy_setopt(curl, CURLOPT_URL, sURL.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)this);

        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);

        if (fUseProxy)
        {
            curl_easy_setopt(curl, CURLOPT_PROXY, addrProxy.ToStringIP().c_str());
            curl_easy_setopt(curl, CURLOPT_PROXYPORT, addrProxy.GetPort());
            curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
        }
    }

    ~DataFeedRequest()
    {
        if (curl)
        {
            curl_easy_cleanup(curl);
            curl = NULL;
        }
    }

    void Perform()
    {
        CURLcode res;
        res = curl_easy_perform(curl);

        if (res == CURLE_OK)
        {
            long http_code = 0;
            if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code) != CURLE_OK)
                throw runtime_error("Unable to get data feed response code");

            if (http_code != 200)
                throw runtime_error((boost::format("Data feed failed: Response code %ld") % http_code).str());

            printf("Received %lu bytes from data feed %s:\n%s\n", (long)result.size(), url.c_str(), result.c_str());
        }
        else
        {
            if (error == "")
                error = (boost::format("Data feed failed: %s") % curl_easy_strerror(res)).str();

            throw runtime_error(error);
        }
    }

    string GetResult() const
    {
        return result;
    }
};

void VerifyDataFeedSignature(const string& strMessage, const string& strSign, const string& strAddress)
{
    CBitcoinAddress addr(strAddress);
    if (!addr.IsValid())
        throw runtime_error("Invalid data feed address");

    CKeyID keyID;
    if (!addr.GetKeyID(keyID))
        throw runtime_error("Data feed address does not refer to key");

    bool fInvalid = false;
    vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);

    if (fInvalid)
        throw runtime_error("Malformed base64 encoding of data feed signature");

    CDataStream ss(SER_GETHASH, 0);
    ss << strMessageMagic;
    ss << strMessage;

    CKey key;
    if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
        throw runtime_error("Unable to set key from data feed signature");

    if (key.GetPubKey().GetID() != keyID)
        throw runtime_error("Data feed signature check failed");
}

bool GetVoteFromDataFeed(const CDataFeed& dataFeed, CVote& voteRet)
{
    bool result = false;

    try
    {
        DataFeedRequest request(dataFeed.sURL);
        request.Perform();

        if (dataFeed.sSignatureAddress != "" && dataFeed.sSignatureURL != "")
        {
            DataFeedRequest signatureRequest(dataFeed.sSignatureURL);
            signatureRequest.Perform();

            VerifyDataFeedSignature(request.GetResult(), signatureRequest.GetResult(), dataFeed.sSignatureAddress);
        }

        Value valReply;
        if (!read_string(request.GetResult(), valReply))
            throw runtime_error("Data feed returned invalid data");

        voteRet = ParseVote(valReply.get_obj());
        result = true;
    }
    catch (exception &e)
    {
        printf("GetVoteFromDataFeed error: %s\n", e.what());
        throw;
    }

    return result;
}

CVote ParseVote(const Object& objVote)
{
    CVote vote;

    BOOST_FOREACH(const Pair& voteAttribute, objVote)
    {
        if (voteAttribute.name_ == "motions")
        {
            BOOST_FOREACH(const Value& motionVoteObject, voteAttribute.value_.get_array())
                vote.vMotion.push_back(uint160(motionVoteObject.get_str()));
        }
        else if (voteAttribute.name_ == "custodians")
        {
            BOOST_FOREACH(const Value& custodianVoteObject, voteAttribute.value_.get_array())
            {
                CCustodianVote custodianVote;
                BOOST_FOREACH(const Pair& custodianVoteAttribute, custodianVoteObject.get_obj())
                {
                    if (custodianVoteAttribute.name_ == "address")
                    {
                        CBitcoinAddress address(custodianVoteAttribute.value_.get_str());
                        if (!address.IsValid())
                            throw runtime_error("Invalid address\n");

                        custodianVote.SetAddress(address);
                        if (custodianVote.cUnit == 'S' || !ValidUnit(custodianVote.cUnit))
                            throw runtime_error("Invalid custodian unit\n");
                    }
                    else if (custodianVoteAttribute.name_ == "amount")
                        custodianVote.nAmount = AmountFromValue(custodianVoteAttribute.value_);
                    else
                        throw runtime_error("Invalid custodian vote object\n");
                }
                vote.vCustodianVote.push_back(custodianVote);
            }
        }
        else if (voteAttribute.name_ == "parkrates")
        {
            BOOST_FOREACH(const Value& parkRateVoteObject, voteAttribute.value_.get_array())
            {
                CParkRateVote parkRateVote;
                BOOST_FOREACH(const Pair& parkRateVoteAttribute, parkRateVoteObject.get_obj())
                {
                    if (parkRateVoteAttribute.name_ == "unit")
                    {
                        parkRateVote.cUnit = parkRateVoteAttribute.value_.get_str()[0];
                        if (parkRateVote.cUnit == 'S' || !ValidUnit(parkRateVote.cUnit))
                            throw runtime_error("Invalid park rate unit\n");
                    }
                    else if (parkRateVoteAttribute.name_ == "rates")
                    {
                        BOOST_FOREACH(const Value& parkRateObject, parkRateVoteAttribute.value_.get_array())
                        {
                            CParkRate parkRate;
                            BOOST_FOREACH(const Pair& parkRateAttribute, parkRateObject.get_obj())
                            {
                                if (parkRateAttribute.name_ == "blocks")
                                {
                                   int blocks = parkRateAttribute.value_.get_int();
                                   double compactDuration = log2(blocks);
                                   double integerPart;
                                   if (modf(compactDuration, &integerPart) != 0.0)
                                       throw runtime_error("Park duration is not a power of 2\n");
                                   if (compactDuration < 0 || compactDuration > 255)
                                       throw runtime_error("Park duration out of range\n");
                                   parkRate.nCompactDuration = compactDuration;
                                }
                                else if (parkRateAttribute.name_ == "rate")
                                {
                                    double dAmount = parkRateAttribute.value_.get_real();
                                    if (dAmount < 0.0 || dAmount > MAX_MONEY)
                                        throw runtime_error("Invalid park rate amount\n");
                                    parkRate.nRate = roundint64(dAmount * COIN_PARK_RATE);
                                    if (!MoneyRange(parkRate.nRate))
                                        throw runtime_error("Invalid park rate amount\n");
                                }
                                else
                                    throw runtime_error("Invalid park rate object\n");
                            }
                            parkRateVote.vParkRate.push_back(parkRate);
                        }
                    }
                    else
                        throw runtime_error("Invalid custodian vote object\n");
                }
                vote.vParkRateVote.push_back(parkRateVote);
            }
        }
        else
            throw runtime_error("Invalid vote object\n");
    }

    return vote;
}

void UpdateFromDataFeed()
{
    CWallet* pwallet = GetWallet('S');
    CDataFeed dataFeed;
    {
        LOCK(pwallet->cs_wallet);
        dataFeed = pwallet->GetDataFeed();
    }

    if (dataFeed.sURL == "")
        return;

    printf("Updating from data feed %s\n", dataFeed.sURL.c_str());

    CVote feedVote;
    if (GetVoteFromDataFeed(dataFeed, feedVote))
    {
        LOCK(pwallet->cs_wallet);
        CVote newVote = pwallet->vote;
        BOOST_FOREACH(const string& sPart, dataFeed.vParts)
        {
            if (sPart == "custodians")
                newVote.vCustodianVote = feedVote.vCustodianVote;
            else if (sPart == "parkrates")
                newVote.vParkRateVote = feedVote.vParkRateVote;
            else if (sPart == "motions")
                newVote.vMotion = feedVote.vMotion;
            else
                throw runtime_error("Invalid part");
        }
        pwallet->SetVote(newVote);
        printf("Vote updated from data feed\n");
    }
}

void ThreadUpdateFromDataFeed(void* parg)
{
    printf("ThreadUpdateFromDataFeed started\n");

    int delay = GetArg("-datafeeddelay", 60);
    int64 lastUpdate = GetTime();

    while (true)
    {
#ifdef TESTING
        Sleep(200);
#else
        Sleep(1000);
#endif

        if (fShutdown)
            break;

        int64 now = GetTime();

        if (now >= lastUpdate + delay)
        {
            strDataFeedError = "";
            try
            {
                UpdateFromDataFeed();
            }
            catch (exception &e)
            {
                printf("UpdateFromDataFeed failed: %s\n", e.what());
                strDataFeedError = string(e.what());
            }

            lastUpdate = now;
        }
    }

    printf("ThreadUpdateFromDataFeed exited\n");
}

void StartUpdateFromDataFeed()
{
    if (!CreateThread(ThreadUpdateFromDataFeed, NULL))
        printf("Error; CreateThread(ThreadUpdateFromDataFeed) failed\n");
}
<|endoftext|>


<commit_before>#include "iostream"
#include "AliFMDInput.h"
#include "AliFMDHit.h"
#include "TFile.h"
#include "TTree.h"
#include "TClonesArray.h"
#include "AliTrackReference.h"
#include "AliFMDStripIndex.h"

//Script to compare the hits and the FMD track references for one event.
//To run:
//>gSystem->Load("libFMDutil")
//>.L CompareTrackRefsAndHits.C++
//>ReadHits t
//>t.Run()
//Note that the order of hits and trackrefs is different.

class ReadHits : public AliFMDInput{

private:
  Int_t nHits;

public:

  ReadHits(){
    AddLoad(kKinematics);
    AddLoad(kHits);
    nHits = 0;
  }

  Bool_t ProcessHit(AliFMDHit* hit, TParticle* p)
  {
    nHits++;
    std::cout<<hit->Px()<<"   "<<hit->Py()<<"   "<<hit->Pz()<<std::endl;
    std::cout<<hit->Detector()<<"   "<<hit->Ring()<<"    "<<hit->Sector()<<"    "<<hit->Strip()<<std::endl;
    return kTRUE;
  }
  Bool_t Finish()
  {
    Int_t nTracks = 0;
    TFile* f=TFile::Open("TrackRefs.root");
    TTree* tree = (TTree*)f->Get("Event0/TreeTR");

    TClonesArray* array=new TClonesArray("AliTrackReference");

    tree->SetBranchAddress("TrackReferences",&array);

    UShort_t det,sec,strip;
    Char_t ring;
    for (int i=0; i<tree->GetEntries(); i++) {
      tree->GetEvent(i);
    for(Int_t j = 0; j <array->GetEntriesFast();j++) {

      AliTrackReference* track = static_cast<AliTrackReference*>(array->At(j));

      if(track->DetectorId()==AliTrackReference::kFMD) {
	nTracks++;
	AliFMDStripIndex::Unpack(track->UserId(),det,ring,sec,strip);
	std::cout<<track->Px()<<"   "<<track->Py()<<"   "<<track->Pz()<<"   "<<track->UserId()<<endl;
	std::cout<<det<<"   "<<ring<<"    "<<sec<<"    "<<strip<<std::endl;
      }

    }

    }
    std::cout<<nTracks<<"     "<<nHits<<std::endl;
    return kTRUE;
  }

};
<commit_msg>Fixes<commit_after>#include "iostream"
#include "AliFMDInput.h"
#include "AliFMDHit.h"
#include "TFile.h"
#include "TTree.h"
#include "TClonesArray.h"
#include "AliTrackReference.h"
#include "AliFMDStripIndex.h"
#include "TParticle.h"
//Script to compare the hits and the FMD track references for one event.
//To run:
//>gSystem->Load("libFMDutil")
//>.L CompareTrackRefsAndHits.C++
//>ReadHits t
//>t.Run()
//Note that the order of hits and trackrefs is different.

class ReadHits : public AliFMDInput{

private:
  Int_t nHits;
  Int_t nTracks;
public:

  ReadHits(){
    AddLoad(kKinematics);
    AddLoad(kTracks);
    AddLoad(kTrackRefs);
    AddLoad(kHits);
    nHits = 0;
    nTracks = 0;
    fGAliceFile.Form("galice.root");
  }

  Bool_t ProcessHit(AliFMDHit* hit, TParticle* p)
  {
    nHits++;
    // std::cout<<hit->Px()<<"   "<<hit->Py()<<"   "<<hit->Pz()<<std::endl;
    //std::cout<<hit->Detector()<<"   "<<hit->Ring()<<"    "<<hit->Sector()<<"    "<<hit->Strip()<<std::endl;
    return kTRUE;
  }
  Bool_t ProcessTrackRef(AliTrackReference* trackRef, TParticle* p)
  {
    UShort_t det,sec,strip;
    Char_t ring;
    if(trackRef->DetectorId() == AliTrackReference::kFMD) {
      nTracks++;
      AliFMDStripIndex::Unpack(trackRef->UserId(),det,ring,sec,strip);
      //std::cout<<p->Px()<<"   "<<p->Py()<<"   "<<p->Pz()<<std::endl;
      //std::cout<<det<<"   "<<ring<<"    "<<sec<<"    "<<strip<<std::endl;
    }

    return kTRUE;
  }

  Bool_t Finish()
  {
    // Int_t nTracks = 0;
    /* TFile* f=TFile::Open("TrackRefs.root");
    TTree* tree = (TTree*)f->Get("Event0/TreeTR");

    TClonesArray* array=new TClonesArray("AliTrackReference");

    tree->SetBranchAddress("TrackReferences",&array);

    UShort_t det,sec,strip;
    Char_t ring;
    for (int i=0; i<tree->GetEntries(); i++) {
      tree->GetEvent(i);
    for(Int_t j = 0; j <array->GetEntriesFast();j++) {

      AliTrackReference* track = static_cast<AliTrackReference*>(array->At(j));

      if(track->DetectorId()==AliTrackReference::kFMD) {
	nTracks++;
	AliFMDStripIndex::Unpack(track->UserId(),det,ring,sec,strip);
	std::cout<<track->Px()<<"   "<<track->Py()<<"   "<<track->Pz()<<"   "<<track->UserId()<<endl;
	std::cout<<det<<"   "<<ring<<"    "<<sec<<"    "<<strip<<std::endl;
      }

    }

  }
    */
    std::cout<<nTracks<<"     "<<nHits<<std::endl;
    return kTRUE;
  }

};
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_common_test.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/autofill_helper.h"
#include "chrome/browser/sync/test/integration/performance/sync_timing_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/webdata/autofill_entry.h"

using autofill_helper::AllProfilesMatch;
using autofill_helper::GetAllKeys;
using autofill_helper::GetAllProfiles;
using autofill_helper::GetKeyCount;
using autofill_helper::GetProfileCount;
using autofill_helper::RemoveKey;
using autofill_helper::SetProfiles;

static const int kNumKeys = 150;
static const int kNumProfiles = 150;

class AutofillSyncPerfTest : public SyncTest {
 public:
  AutofillSyncPerfTest()
      : SyncTest(TWO_CLIENT),
        guid_number_(0),
        name_number_(0),
        value_number_(0) {}

  // Adds |num_profiles| new autofill profiles to the sync profile |profile|.
  void AddProfiles(int profile, int num_profiles);

  // Updates all autofill profiles for the sync profile |profile|.
  void UpdateProfiles(int profile);

  // Removes all autofill profiles from |profile|.
  void RemoveProfiles(int profile);

  // Adds |num_keys| new autofill keys to the sync profile |profile|.
  void AddKeys(int profile, int num_keys);

  // Removes all autofill keys from |profile|.
  void RemoveKeys(int profile);

 private:
  // Returns a new unique autofill profile.
  const AutofillProfile NextAutofillProfile();

  // Returns a new unique autofill key.
  const AutofillKey NextAutofillKey();

  // Returns an unused unique guid.
  const std::string NextGUID();

  // Returns a unique guid based on the input integer |n|.
  const std::string IntToGUID(int n);

  // Returns a new unused unique name.
  const std::string NextName();

  // Returns a unique name based on the input integer |n|.
  const std::string IntToName(int n);

  // Returns a new unused unique value for autofill entries.
  const std::string NextValue();

  // Returnes a unique value based on the input integer |n|.
  const std::string IntToValue(int n);

  int guid_number_;
  int name_number_;
  int value_number_;
  DISALLOW_COPY_AND_ASSIGN(AutofillSyncPerfTest);
};

void AutofillSyncPerfTest::AddProfiles(int profile, int num_profiles) {
  const std::vector<AutofillProfile*>& all_profiles =
      GetAllProfiles(profile);
  std::vector<AutofillProfile> autofill_profiles;
  for (size_t i = 0; i < all_profiles.size(); ++i) {
    autofill_profiles.push_back(*all_profiles[i]);
  }
  for (int i = 0; i < num_profiles; ++i) {
    autofill_profiles.push_back(NextAutofillProfile());
  }
  SetProfiles(profile, &autofill_profiles);
}

void AutofillSyncPerfTest::UpdateProfiles(int profile) {
  const std::vector<AutofillProfile*>& all_profiles =
      GetAllProfiles(profile);
  std::vector<AutofillProfile> autofill_profiles;
  for (size_t i = 0; i < all_profiles.size(); ++i) {
    autofill_profiles.push_back(*all_profiles[i]);
    autofill_profiles.back().SetInfo(AutofillFieldType(NAME_FIRST),
                                     UTF8ToUTF16(NextName()));
  }
  SetProfiles(profile, &autofill_profiles);
}

void AutofillSyncPerfTest::RemoveProfiles(int profile) {
  std::vector<AutofillProfile> empty;
  SetProfiles(profile, &empty);
}

void AutofillSyncPerfTest::AddKeys(int profile, int num_keys) {
  std::set<AutofillKey> keys;
  for (int i = 0; i < num_keys; ++i) {
    keys.insert(NextAutofillKey());
  }
  autofill_helper::AddKeys(profile, keys);
}

void AutofillSyncPerfTest::RemoveKeys(int profile) {
  std::set<AutofillEntry> keys = GetAllKeys(profile);
  for (std::set<AutofillEntry>::const_iterator it = keys.begin();
       it != keys.end(); ++it) {
    RemoveKey(profile, it->key());
  }
}

const AutofillProfile AutofillSyncPerfTest::NextAutofillProfile() {
  AutofillProfile profile;
  autofill_test::SetProfileInfoWithGuid(&profile, NextGUID().c_str(),
                                        NextName().c_str(), "", "", "", "", "",
                                        "", "", "", "", "", "");
  return profile;
}

const AutofillKey AutofillSyncPerfTest::NextAutofillKey() {
  return AutofillKey(NextName().c_str(), NextName().c_str());
}

const std::string AutofillSyncPerfTest::NextGUID() {
  return IntToGUID(guid_number_++);
}

const std::string AutofillSyncPerfTest::IntToGUID(int n) {
  return StringPrintf("00000000-0000-0000-0000-%012X", n);
}

const std::string AutofillSyncPerfTest::NextName() {
  return IntToName(name_number_++);
}

const std::string AutofillSyncPerfTest::IntToName(int n) {
  return StringPrintf("Name%d", n);
}

const std::string AutofillSyncPerfTest::NextValue() {
  return IntToValue(value_number_++);
}

const std::string AutofillSyncPerfTest::IntToValue(int n) {
  return StringPrintf("Value%d", n);
}

IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, AutofillProfiles_P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  // TCM ID - 7557873.
  AddProfiles(0, kNumProfiles);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumProfiles, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "add_autofill_profiles", dt);

  // TCM ID - 7549835.
  UpdateProfiles(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumProfiles, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "update_autofill_profiles", dt);

  // TCM ID - 7553678.
  RemoveProfiles(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "delete_autofill_profiles", dt);
}

IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, Autofill_P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  AddKeys(0, kNumKeys);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumKeys, GetKeyCount(1));
  SyncTimingHelper::PrintResult("autofill", "add_autofill_keys", dt);

  RemoveKeys(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetKeyCount(1));
  SyncTimingHelper::PrintResult("autofill", "delete_autofill_keys", dt);
}
<commit_msg>Mark Autofill_P0 flaky on Linux.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_common_test.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/autofill_helper.h"
#include "chrome/browser/sync/test/integration/performance/sync_timing_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/webdata/autofill_entry.h"

using autofill_helper::AllProfilesMatch;
using autofill_helper::GetAllKeys;
using autofill_helper::GetAllProfiles;
using autofill_helper::GetKeyCount;
using autofill_helper::GetProfileCount;
using autofill_helper::RemoveKey;
using autofill_helper::SetProfiles;

static const int kNumKeys = 150;
static const int kNumProfiles = 150;

class AutofillSyncPerfTest : public SyncTest {
 public:
  AutofillSyncPerfTest()
      : SyncTest(TWO_CLIENT),
        guid_number_(0),
        name_number_(0),
        value_number_(0) {}

  // Adds |num_profiles| new autofill profiles to the sync profile |profile|.
  void AddProfiles(int profile, int num_profiles);

  // Updates all autofill profiles for the sync profile |profile|.
  void UpdateProfiles(int profile);

  // Removes all autofill profiles from |profile|.
  void RemoveProfiles(int profile);

  // Adds |num_keys| new autofill keys to the sync profile |profile|.
  void AddKeys(int profile, int num_keys);

  // Removes all autofill keys from |profile|.
  void RemoveKeys(int profile);

 private:
  // Returns a new unique autofill profile.
  const AutofillProfile NextAutofillProfile();

  // Returns a new unique autofill key.
  const AutofillKey NextAutofillKey();

  // Returns an unused unique guid.
  const std::string NextGUID();

  // Returns a unique guid based on the input integer |n|.
  const std::string IntToGUID(int n);

  // Returns a new unused unique name.
  const std::string NextName();

  // Returns a unique name based on the input integer |n|.
  const std::string IntToName(int n);

  // Returns a new unused unique value for autofill entries.
  const std::string NextValue();

  // Returnes a unique value based on the input integer |n|.
  const std::string IntToValue(int n);

  int guid_number_;
  int name_number_;
  int value_number_;
  DISALLOW_COPY_AND_ASSIGN(AutofillSyncPerfTest);
};

void AutofillSyncPerfTest::AddProfiles(int profile, int num_profiles) {
  const std::vector<AutofillProfile*>& all_profiles =
      GetAllProfiles(profile);
  std::vector<AutofillProfile> autofill_profiles;
  for (size_t i = 0; i < all_profiles.size(); ++i) {
    autofill_profiles.push_back(*all_profiles[i]);
  }
  for (int i = 0; i < num_profiles; ++i) {
    autofill_profiles.push_back(NextAutofillProfile());
  }
  SetProfiles(profile, &autofill_profiles);
}

void AutofillSyncPerfTest::UpdateProfiles(int profile) {
  const std::vector<AutofillProfile*>& all_profiles =
      GetAllProfiles(profile);
  std::vector<AutofillProfile> autofill_profiles;
  for (size_t i = 0; i < all_profiles.size(); ++i) {
    autofill_profiles.push_back(*all_profiles[i]);
    autofill_profiles.back().SetInfo(AutofillFieldType(NAME_FIRST),
                                     UTF8ToUTF16(NextName()));
  }
  SetProfiles(profile, &autofill_profiles);
}

void AutofillSyncPerfTest::RemoveProfiles(int profile) {
  std::vector<AutofillProfile> empty;
  SetProfiles(profile, &empty);
}

void AutofillSyncPerfTest::AddKeys(int profile, int num_keys) {
  std::set<AutofillKey> keys;
  for (int i = 0; i < num_keys; ++i) {
    keys.insert(NextAutofillKey());
  }
  autofill_helper::AddKeys(profile, keys);
}

void AutofillSyncPerfTest::RemoveKeys(int profile) {
  std::set<AutofillEntry> keys = GetAllKeys(profile);
  for (std::set<AutofillEntry>::const_iterator it = keys.begin();
       it != keys.end(); ++it) {
    RemoveKey(profile, it->key());
  }
}

const AutofillProfile AutofillSyncPerfTest::NextAutofillProfile() {
  AutofillProfile profile;
  autofill_test::SetProfileInfoWithGuid(&profile, NextGUID().c_str(),
                                        NextName().c_str(), "", "", "", "", "",
                                        "", "", "", "", "", "");
  return profile;
}

const AutofillKey AutofillSyncPerfTest::NextAutofillKey() {
  return AutofillKey(NextName().c_str(), NextName().c_str());
}

const std::string AutofillSyncPerfTest::NextGUID() {
  return IntToGUID(guid_number_++);
}

const std::string AutofillSyncPerfTest::IntToGUID(int n) {
  return StringPrintf("00000000-0000-0000-0000-%012X", n);
}

const std::string AutofillSyncPerfTest::NextName() {
  return IntToName(name_number_++);
}

const std::string AutofillSyncPerfTest::IntToName(int n) {
  return StringPrintf("Name%d", n);
}

const std::string AutofillSyncPerfTest::NextValue() {
  return IntToValue(value_number_++);
}

const std::string AutofillSyncPerfTest::IntToValue(int n) {
  return StringPrintf("Value%d", n);
}

IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, AutofillProfiles_P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  // TCM ID - 7557873.
  AddProfiles(0, kNumProfiles);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumProfiles, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "add_autofill_profiles", dt);

  // TCM ID - 7549835.
  UpdateProfiles(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumProfiles, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "update_autofill_profiles", dt);

  // TCM ID - 7553678.
  RemoveProfiles(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetProfileCount(1));
  SyncTimingHelper::PrintResult("autofill", "delete_autofill_profiles", dt);
}

// Flaky on Linux, see http://crbug.com/102948
#if defined(OS_LINUX)
#define MAYBE_Autofill_P0 FLAKY_Autofill_P0
#else
#define MAYBE_Autofill_P0 Autofill_P0
#endif

IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, MAYBE_Autofill_P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  AddKeys(0, kNumKeys);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumKeys, GetKeyCount(1));
  SyncTimingHelper::PrintResult("autofill", "add_autofill_keys", dt);

  RemoveKeys(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetKeyCount(1));
  SyncTimingHelper::PrintResult("autofill", "delete_autofill_keys", dt);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractGrid.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkExtractGrid.h"

#include "vtkBoundingBox.h"
#include "vtkCellData.h"
#include "vtkExtractStructuredGridHelper.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStructuredGrid.h"

vtkStandardNewMacro(vtkExtractGrid);

// Construct object to extract all of the input data.
vtkExtractGrid::vtkExtractGrid()
{
  this->VOI[0] = this->VOI[2] = this->VOI[4] = 0;
  this->VOI[1] = this->VOI[3] = this->VOI[5] = VTK_INT_MAX;

  this->SampleRate[0] = this->SampleRate[1] = this->SampleRate[2] = 1;
  this->IncludeBoundary = 0;
  this->Internal = vtkExtractStructuredGridHelper::New();
}

vtkExtractGrid::~vtkExtractGrid()
{
  if( this->Internal != NULL )
    {
    this->Internal->Delete();
    }
}

int vtkExtractGrid::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  int wholeExtent[6], outWholeExt[6];

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent);

  this->Internal->Initialize(
      this->VOI,wholeExtent,this->SampleRate,(this->IncludeBoundary==1));
  this->Internal->GetOutputWholeExtent(outWholeExt);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               outWholeExt, 6);
  return 1;
}

int vtkExtractGrid::RequestUpdateExtent(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  int i;

  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  bool emptyExtent = false;
  int uExt[6];
  for (i=0; i<3; i++)
    {
    if (this->Internal->GetSize(i) < 1)
      {
      uExt[0] = uExt[2] = uExt[4] = 0;
      uExt[1] = uExt[3] = uExt[5] = -1;
      emptyExtent = true;
      break;
      }
    }

  if (!emptyExtent)
    {
    // Find input update extent based on requested output
    // extent
    int oUExt[6];
    outputVector->GetInformationObject(0)->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), oUExt);
    for (i=0; i<3; i++)
      {
      int idx = oUExt[2*i];
      if (idx < 0 || oUExt[2*i] >= (int)this->Internal->GetSize(i))
        {
        vtkWarningMacro("Requested extent outside whole extent.")
        idx = 0;
        }
      uExt[2*i] = this->Internal->GetMappedExtentValueFromIndex(i, idx);
      int jdx = oUExt[2*i+1];
      if (jdx < idx || jdx >= (int)this->Internal->GetSize(i))
        {
        vtkWarningMacro("Requested extent outside whole extent.")
        jdx = 0;
        }
      uExt[2*i + 1] = this->Internal->GetMappedExtentValueFromIndex(i, jdx);
      }
    }
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), uExt, 6);
  // We can handle anything.
  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 0);

  return 1;
}

//------------------------------------------------------------------------------
int vtkExtractGrid::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  return this->RequestDataImpl(this->VOI, inputVector, outputVector) ? 0 : 1;
}

//------------------------------------------------------------------------------
bool vtkExtractGrid::RequestDataImpl(int voi[6],
                                     vtkInformationVector **inputVector,
                                     vtkInformationVector *outputVector)
{
  if( (this->SampleRate[0] < 1) ||
      (this->SampleRate[1] < 1) ||
      (this->SampleRate[2] < 1) )
    {
    vtkErrorMacro("SampleRate must be >= 1 in all 3 dimensions!");
    return false;
    }

  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and output
  vtkStructuredGrid *input = vtkStructuredGrid::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkStructuredGrid *output = vtkStructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkPointData *pd=input->GetPointData();
  vtkCellData *cd=input->GetCellData();
  vtkPointData *outPD=output->GetPointData();
  vtkCellData *outCD=output->GetCellData();
  int *inExt;
  int *outExt;
  vtkPoints *newPts, *inPts;

  vtkDebugMacro(<< "Extracting Grid");

  if (input->GetNumberOfPoints() == 0)
    {
    return true;
    }

  inPts = input->GetPoints();
  inExt = input->GetExtent();

  int begin[3];
  int end[3];
  this->Internal->ComputeBeginAndEnd(inExt,this->VOI,begin,end);
  output->SetExtent(begin[0], end[0], begin[1], end[1], begin[2], end[2]);

  newPts = inPts->NewInstance();
  outExt = output->GetExtent();

  this->Internal->CopyPointsAndPointData(inExt,outExt,pd,inPts,outPD,newPts);
  output->SetPoints(newPts);
  newPts->Delete();

  this->Internal->CopyCellData(inExt,outExt,cd,outCD);

  return true;
}

void vtkExtractGrid::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "VOI: \n";
  os << indent << "  Imin,Imax: (" << this->VOI[0] << ", "
     << this->VOI[1] << ")\n";
  os << indent << "  Jmin,Jmax: (" << this->VOI[2] << ", "
     << this->VOI[3] << ")\n";
  os << indent << "  Kmin,Kmax: (" << this->VOI[4] << ", "
     << this->VOI[5] << ")\n";

  os << indent << "Sample Rate: (" << this->SampleRate[0] << ", "
               << this->SampleRate[1] << ", "
               << this->SampleRate[2] << ")\n";

  os << indent << "Include Boundary: "
     << (this->IncludeBoundary ? "On\n" : "Off\n");
}
<commit_msg>COMP: fix unused warning<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractGrid.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkExtractGrid.h"

#include "vtkBoundingBox.h"
#include "vtkCellData.h"
#include "vtkExtractStructuredGridHelper.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStructuredGrid.h"

vtkStandardNewMacro(vtkExtractGrid);

// Construct object to extract all of the input data.
vtkExtractGrid::vtkExtractGrid()
{
  this->VOI[0] = this->VOI[2] = this->VOI[4] = 0;
  this->VOI[1] = this->VOI[3] = this->VOI[5] = VTK_INT_MAX;

  this->SampleRate[0] = this->SampleRate[1] = this->SampleRate[2] = 1;
  this->IncludeBoundary = 0;
  this->Internal = vtkExtractStructuredGridHelper::New();
}

vtkExtractGrid::~vtkExtractGrid()
{
  if( this->Internal != NULL )
    {
    this->Internal->Delete();
    }
}

int vtkExtractGrid::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  int wholeExtent[6], outWholeExt[6];

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent);

  this->Internal->Initialize(
      this->VOI,wholeExtent,this->SampleRate,(this->IncludeBoundary==1));
  this->Internal->GetOutputWholeExtent(outWholeExt);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               outWholeExt, 6);
  return 1;
}

int vtkExtractGrid::RequestUpdateExtent(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  int i;

  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  bool emptyExtent = false;
  int uExt[6];
  for (i=0; i<3; i++)
    {
    if (this->Internal->GetSize(i) < 1)
      {
      uExt[0] = uExt[2] = uExt[4] = 0;
      uExt[1] = uExt[3] = uExt[5] = -1;
      emptyExtent = true;
      break;
      }
    }

  if (!emptyExtent)
    {
    // Find input update extent based on requested output
    // extent
    int oUExt[6];
    outputVector->GetInformationObject(0)->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), oUExt);
    for (i=0; i<3; i++)
      {
      int idx = oUExt[2*i];
      if (idx < 0 || oUExt[2*i] >= (int)this->Internal->GetSize(i))
        {
        vtkWarningMacro("Requested extent outside whole extent.")
        idx = 0;
        }
      uExt[2*i] = this->Internal->GetMappedExtentValueFromIndex(i, idx);
      int jdx = oUExt[2*i+1];
      if (jdx < idx || jdx >= (int)this->Internal->GetSize(i))
        {
        vtkWarningMacro("Requested extent outside whole extent.")
        jdx = 0;
        }
      uExt[2*i + 1] = this->Internal->GetMappedExtentValueFromIndex(i, jdx);
      }
    }
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), uExt, 6);
  // We can handle anything.
  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 0);

  return 1;
}

//------------------------------------------------------------------------------
int vtkExtractGrid::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  return this->RequestDataImpl(this->VOI, inputVector, outputVector) ? 0 : 1;
}

//------------------------------------------------------------------------------
bool vtkExtractGrid::RequestDataImpl(int vtkNotUsed(voi)[6],
                                     vtkInformationVector **inputVector,
                                     vtkInformationVector *outputVector)
{
  if( (this->SampleRate[0] < 1) ||
      (this->SampleRate[1] < 1) ||
      (this->SampleRate[2] < 1) )
    {
    vtkErrorMacro("SampleRate must be >= 1 in all 3 dimensions!");
    return false;
    }

  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and output
  vtkStructuredGrid *input = vtkStructuredGrid::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkStructuredGrid *output = vtkStructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkPointData *pd=input->GetPointData();
  vtkCellData *cd=input->GetCellData();
  vtkPointData *outPD=output->GetPointData();
  vtkCellData *outCD=output->GetCellData();
  int *inExt;
  int *outExt;
  vtkPoints *newPts, *inPts;

  vtkDebugMacro(<< "Extracting Grid");

  if (input->GetNumberOfPoints() == 0)
    {
    return true;
    }

  inPts = input->GetPoints();
  inExt = input->GetExtent();

  int begin[3];
  int end[3];
  this->Internal->ComputeBeginAndEnd(inExt,this->VOI,begin,end);
  output->SetExtent(begin[0], end[0], begin[1], end[1], begin[2], end[2]);

  newPts = inPts->NewInstance();
  outExt = output->GetExtent();

  this->Internal->CopyPointsAndPointData(inExt,outExt,pd,inPts,outPD,newPts);
  output->SetPoints(newPts);
  newPts->Delete();

  this->Internal->CopyCellData(inExt,outExt,cd,outCD);

  return true;
}

void vtkExtractGrid::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "VOI: \n";
  os << indent << "  Imin,Imax: (" << this->VOI[0] << ", "
     << this->VOI[1] << ")\n";
  os << indent << "  Jmin,Jmax: (" << this->VOI[2] << ", "
     << this->VOI[3] << ")\n";
  os << indent << "  Kmin,Kmax: (" << this->VOI[4] << ", "
     << this->VOI[5] << ")\n";

  os << indent << "Sample Rate: (" << this->SampleRate[0] << ", "
               << this->SampleRate[1] << ", "
               << this->SampleRate[2] << ")\n";

  os << indent << "Include Boundary: "
     << (this->IncludeBoundary ? "On\n" : "Off\n");
}
<|endoftext|>