<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$
** 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 "private/qdeclarativerepeater_p.h"
#include "private/qdeclarativerepeater_p_p.h"

#include "private/qdeclarativevisualitemmodel_p.h"
#include <private/qdeclarativeglobal_p.h>
#include <qdeclarativelistaccessor_p.h>

#include <qlistmodelinterface_p.h>

QT_BEGIN_NAMESPACE
QDeclarativeRepeaterPrivate::QDeclarativeRepeaterPrivate()
: model(0), ownModel(false)
{
}

QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
{
    if (ownModel)
        delete model;
}

/*!
    \qmlclass Repeater QDeclarativeRepeater
    \since 4.7
    \inherits Item

    \brief The Repeater item allows you to repeat an Item-based component using a model.

    The Repeater item is used when you want to create a large number of
    similar items.  For each entry in the model, an item is instantiated
    in a context seeded with data from the model.  If the repeater will
    be instantiating a large number of instances, it may be more efficient to
    use one of Qt Declarative's \l {xmlViews}{view items}.

    The model may be either an object list, a string list, a number or a Qt model.
    In each case, the data element and the index is exposed to each instantiated
    component.

    The index is always exposed as an accessible \c index property.
    In the case of an object or string list, the data element (of type string
    or object) is available as the \c modelData property.  In the case of a Qt model,
    all roles are available as named properties just like in the view classes. The
    following example shows how to use the index property inside the instantiated
    items.

    \snippet doc/src/snippets/declarative/repeater-index.qml 0

    \image repeater-index.png

    Items instantiated by the Repeater are inserted, in order, as
    children of the Repeater's parent.  The insertion starts immediately after
    the repeater's position in its parent stacking list.  This is to allow
    you to use a Repeater inside a layout.  The following QML example shows how
    the instantiated items would visually appear stacked between the red and
    blue rectangles.

    \snippet doc/src/snippets/declarative/repeater.qml 0

    \image repeater.png

    The repeater instance continues to own all items it instantiates, even
    if they are otherwise manipulated.  It is illegal to manually remove an item
    created by the Repeater.

    \note Repeater is Item-based, and cannot be used to repeat non-Item-derived objects.
    For example, it cannot be used to repeat QtObjects.
    \badcode
    Item {
        //XXX illegal. Can't repeat QtObject as it doesn't derive from Item.
        Repeater {
            model: 10
            QtObject {}
        }
    }
    \endcode
 */

/*!
    \internal
    \class QDeclarativeRepeater
    \qmlclass Repeater
 */

/*!
    Create a new QDeclarativeRepeater instance.
 */
QDeclarativeRepeater::QDeclarativeRepeater(QDeclarativeItem *parent)
  : QDeclarativeItem(*(new QDeclarativeRepeaterPrivate), parent)
{
}

/*!
    Destroy the repeater instance.  All items it instantiated are also
    destroyed.
 */
QDeclarativeRepeater::~QDeclarativeRepeater()
{
}

/*!
    \qmlproperty any Repeater::model

    The model providing data for the repeater.

    The model may be either an object list, a string list, a number or a Qt model.
    In each case, the data element and the index is exposed to each instantiated
    component.  The index is always exposed as an accessible \c index property.
    In the case of an object or string list, the data element (of type string
    or object) is available as the \c modelData property.  In the case of a Qt model,
    all roles are available as named properties just like in the view classes.

    As a special case the model can also be merely a number. In this case it will
    create that many instances of the component. They will also be assigned an index
    based on the order they are created.

    Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.

    \sa {qmlmodels}{Data Models}
*/
QVariant QDeclarativeRepeater::model() const
{
    Q_D(const QDeclarativeRepeater);
    return d->dataSource;
}

void QDeclarativeRepeater::setModel(const QVariant &model)
{
    Q_D(QDeclarativeRepeater);
    if (d->dataSource == model)
        return;

    clear();
    if (d->model) {
        disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        disconnect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
    */
    }
    d->dataSource = model;
    emit modelChanged();
    QObject *object = qvariant_cast<QObject*>(model);
    QDeclarativeVisualModel *vim = 0;
    if (object && (vim = qobject_cast<QDeclarativeVisualModel *>(object))) {
        if (d->ownModel) {
            delete d->model;
            d->ownModel = false;
        }
        d->model = vim;
    } else {
        if (!d->ownModel) {
            d->model = new QDeclarativeVisualDataModel(qmlContext(this));
            d->ownModel = true;
        }
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            dataModel->setModel(model);
    }
    if (d->model) {
        connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        connect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
        */
        regenerate();
        emit countChanged();
    }
}

/*!
    \qmlproperty Component Repeater::delegate
    \default

    The delegate provides a template defining each item instantiated by the repeater.
    The index is exposed as an accessible \c index property.  Properties of the
    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
 */
QDeclarativeComponent *QDeclarativeRepeater::delegate() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model) {
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            return dataModel->delegate();
    }

    return 0;
}

void QDeclarativeRepeater::setDelegate(QDeclarativeComponent *delegate)
{
    Q_D(QDeclarativeRepeater);
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
       if (delegate == dataModel->delegate())
           return;

    if (!d->ownModel) {
        d->model = new QDeclarativeVisualDataModel(qmlContext(this));
        d->ownModel = true;
    }
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) {
        dataModel->setDelegate(delegate);
        regenerate();
        emit delegateChanged();
    }
}

/*!
    \qmlproperty int Repeater::count

    This property holds the number of items in the repeater.
*/
int QDeclarativeRepeater::count() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model)
        return d->model->count();
    return 0;
}

/*!
    \internal
 */
void QDeclarativeRepeater::componentComplete()
{
    QDeclarativeItem::componentComplete();
    regenerate();
}

/*!
    \internal
 */
QVariant QDeclarativeRepeater::itemChange(GraphicsItemChange change,
                                       const QVariant &value)
{
    QVariant rv = QDeclarativeItem::itemChange(change, value);
    if (change == ItemParentHasChanged) {
        regenerate();
    }

    return rv;
}

void QDeclarativeRepeater::clear()
{
    Q_D(QDeclarativeRepeater);
    if (d->model) {
        foreach (QDeclarativeItem *item, d->deletables) {
            d->model->release(item);
        }
    }
    d->deletables.clear();
}

/*!
    \internal
 */
void QDeclarativeRepeater::regenerate()
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;

    clear();

    if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
        return;

    for (int ii = 0; ii < count(); ++ii) {
        QDeclarativeItem *item = d->model->item(ii);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            item->stackBefore(this);
            d->deletables << item;
        }
    }
}

void QDeclarativeRepeater::itemsInserted(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;
    for (int i = 0; i < count; ++i) {
        int modelIndex = index + i;
        QDeclarativeItem *item = d->model->item(modelIndex);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            if (modelIndex < d->deletables.count())
                item->stackBefore(d->deletables.at(modelIndex));
            else
                item->stackBefore(this);
            d->deletables.insert(modelIndex, item);
        }
    }
}

void QDeclarativeRepeater::itemsRemoved(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;
    while (count--) {
        QDeclarativeItem *item = d->deletables.takeAt(index);
        if (item) {
            d->model->release(item);
        }
    }
}

void QDeclarativeRepeater::itemsMoved(int from, int to, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;
    QList<QDeclarativeItem*> removed;
    int removedCount = count;
    while (removedCount--)
        removed << d->deletables.takeAt(from);
    for (int i = 0; i < count; ++i)
        d->deletables.insert(to + i, removed.at(i));
    d->deletables.last()->stackBefore(this);
    for (int i = d->model->count()-1; i > 0; --i) {
        QDeclarativeItem *item = d->deletables.at(i-1);
        item->stackBefore(d->deletables.at(i));
    }
}

void QDeclarativeRepeater::modelReset()
{
    if (!isComponentComplete())
        return;
    regenerate();
}

QT_END_NAMESPACE
<commit_msg>Don't crash on invalid model remove signal.<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$
** 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 "private/qdeclarativerepeater_p.h"
#include "private/qdeclarativerepeater_p_p.h"

#include "private/qdeclarativevisualitemmodel_p.h"
#include <private/qdeclarativeglobal_p.h>
#include <qdeclarativelistaccessor_p.h>

#include <qlistmodelinterface_p.h>

QT_BEGIN_NAMESPACE
QDeclarativeRepeaterPrivate::QDeclarativeRepeaterPrivate()
: model(0), ownModel(false)
{
}

QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
{
    if (ownModel)
        delete model;
}

/*!
    \qmlclass Repeater QDeclarativeRepeater
    \since 4.7
    \inherits Item

    \brief The Repeater item allows you to repeat an Item-based component using a model.

    The Repeater item is used when you want to create a large number of
    similar items.  For each entry in the model, an item is instantiated
    in a context seeded with data from the model.  If the repeater will
    be instantiating a large number of instances, it may be more efficient to
    use one of Qt Declarative's \l {xmlViews}{view items}.

    The model may be either an object list, a string list, a number or a Qt model.
    In each case, the data element and the index is exposed to each instantiated
    component.

    The index is always exposed as an accessible \c index property.
    In the case of an object or string list, the data element (of type string
    or object) is available as the \c modelData property.  In the case of a Qt model,
    all roles are available as named properties just like in the view classes. The
    following example shows how to use the index property inside the instantiated
    items.

    \snippet doc/src/snippets/declarative/repeater-index.qml 0

    \image repeater-index.png

    Items instantiated by the Repeater are inserted, in order, as
    children of the Repeater's parent.  The insertion starts immediately after
    the repeater's position in its parent stacking list.  This is to allow
    you to use a Repeater inside a layout.  The following QML example shows how
    the instantiated items would visually appear stacked between the red and
    blue rectangles.

    \snippet doc/src/snippets/declarative/repeater.qml 0

    \image repeater.png

    The repeater instance continues to own all items it instantiates, even
    if they are otherwise manipulated.  It is illegal to manually remove an item
    created by the Repeater.

    \note Repeater is Item-based, and cannot be used to repeat non-Item-derived objects.
    For example, it cannot be used to repeat QtObjects.
    \badcode
    Item {
        //XXX illegal. Can't repeat QtObject as it doesn't derive from Item.
        Repeater {
            model: 10
            QtObject {}
        }
    }
    \endcode
 */

/*!
    \internal
    \class QDeclarativeRepeater
    \qmlclass Repeater
 */

/*!
    Create a new QDeclarativeRepeater instance.
 */
QDeclarativeRepeater::QDeclarativeRepeater(QDeclarativeItem *parent)
  : QDeclarativeItem(*(new QDeclarativeRepeaterPrivate), parent)
{
}

/*!
    Destroy the repeater instance.  All items it instantiated are also
    destroyed.
 */
QDeclarativeRepeater::~QDeclarativeRepeater()
{
}

/*!
    \qmlproperty any Repeater::model

    The model providing data for the repeater.

    The model may be either an object list, a string list, a number or a Qt model.
    In each case, the data element and the index is exposed to each instantiated
    component.  The index is always exposed as an accessible \c index property.
    In the case of an object or string list, the data element (of type string
    or object) is available as the \c modelData property.  In the case of a Qt model,
    all roles are available as named properties just like in the view classes.

    As a special case the model can also be merely a number. In this case it will
    create that many instances of the component. They will also be assigned an index
    based on the order they are created.

    Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.

    \sa {qmlmodels}{Data Models}
*/
QVariant QDeclarativeRepeater::model() const
{
    Q_D(const QDeclarativeRepeater);
    return d->dataSource;
}

void QDeclarativeRepeater::setModel(const QVariant &model)
{
    Q_D(QDeclarativeRepeater);
    if (d->dataSource == model)
        return;

    clear();
    if (d->model) {
        disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        disconnect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
    */
    }
    d->dataSource = model;
    emit modelChanged();
    QObject *object = qvariant_cast<QObject*>(model);
    QDeclarativeVisualModel *vim = 0;
    if (object && (vim = qobject_cast<QDeclarativeVisualModel *>(object))) {
        if (d->ownModel) {
            delete d->model;
            d->ownModel = false;
        }
        d->model = vim;
    } else {
        if (!d->ownModel) {
            d->model = new QDeclarativeVisualDataModel(qmlContext(this));
            d->ownModel = true;
        }
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            dataModel->setModel(model);
    }
    if (d->model) {
        connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        connect(d->model, SIGNAL(createdItem(int, QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
        */
        regenerate();
        emit countChanged();
    }
}

/*!
    \qmlproperty Component Repeater::delegate
    \default

    The delegate provides a template defining each item instantiated by the repeater.
    The index is exposed as an accessible \c index property.  Properties of the
    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
 */
QDeclarativeComponent *QDeclarativeRepeater::delegate() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model) {
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            return dataModel->delegate();
    }

    return 0;
}

void QDeclarativeRepeater::setDelegate(QDeclarativeComponent *delegate)
{
    Q_D(QDeclarativeRepeater);
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
       if (delegate == dataModel->delegate())
           return;

    if (!d->ownModel) {
        d->model = new QDeclarativeVisualDataModel(qmlContext(this));
        d->ownModel = true;
    }
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) {
        dataModel->setDelegate(delegate);
        regenerate();
        emit delegateChanged();
    }
}

/*!
    \qmlproperty int Repeater::count

    This property holds the number of items in the repeater.
*/
int QDeclarativeRepeater::count() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model)
        return d->model->count();
    return 0;
}

/*!
    \internal
 */
void QDeclarativeRepeater::componentComplete()
{
    QDeclarativeItem::componentComplete();
    regenerate();
}

/*!
    \internal
 */
QVariant QDeclarativeRepeater::itemChange(GraphicsItemChange change,
                                       const QVariant &value)
{
    QVariant rv = QDeclarativeItem::itemChange(change, value);
    if (change == ItemParentHasChanged) {
        regenerate();
    }

    return rv;
}

void QDeclarativeRepeater::clear()
{
    Q_D(QDeclarativeRepeater);
    if (d->model) {
        foreach (QDeclarativeItem *item, d->deletables) {
            d->model->release(item);
        }
    }
    d->deletables.clear();
}

/*!
    \internal
 */
void QDeclarativeRepeater::regenerate()
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;

    clear();

    if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
        return;

    for (int ii = 0; ii < count(); ++ii) {
        QDeclarativeItem *item = d->model->item(ii);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            item->stackBefore(this);
            d->deletables << item;
        }
    }
}

void QDeclarativeRepeater::itemsInserted(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;
    for (int i = 0; i < count; ++i) {
        int modelIndex = index + i;
        QDeclarativeItem *item = d->model->item(modelIndex);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            if (modelIndex < d->deletables.count())
                item->stackBefore(d->deletables.at(modelIndex));
            else
                item->stackBefore(this);
            d->deletables.insert(modelIndex, item);
        }
    }
}

void QDeclarativeRepeater::itemsRemoved(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete() || count <= 0)
        return;
    while (count--) {
        QDeclarativeItem *item = d->deletables.takeAt(index);
        if (item)
            d->model->release(item);
        else
            break;
    }
}

void QDeclarativeRepeater::itemsMoved(int from, int to, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete() || count <= 0)
        return;
    if (from + count > d->deletables.count()) {
        regenerate();
        return;
    }
    QList<QDeclarativeItem*> removed;
    int removedCount = count;
    while (removedCount--)
        removed << d->deletables.takeAt(from);
    for (int i = 0; i < count; ++i)
        d->deletables.insert(to + i, removed.at(i));
    d->deletables.last()->stackBefore(this);
    for (int i = d->model->count()-1; i > 0; --i) {
        QDeclarativeItem *item = d->deletables.at(i-1);
        item->stackBefore(d->deletables.at(i));
    }
}

void QDeclarativeRepeater::modelReset()
{
    if (!isComponentComplete())
        return;
    regenerate();
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: javacontext.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:11:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include "com/sun/star/uno/Any.hxx"
#endif
#ifndef _COM_SUN_STAR_UNO_TYPE_HXX_
#include "com/sun/star/uno/Type.hxx"
#endif
#ifndef _SVTOOLS_SVTDATA_HXX
#include "svtdata.hxx"
#endif
#ifndef _SVTOOLS_JAVACONTEXT_HXX_
#include "javacontext.hxx"
#endif
#ifndef _SVTOOLS_JAVAINTERACTION_HXX_
#include "javainteractionhandler.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::task;
namespace svt
{

JavaContext::JavaContext( const Reference< XCurrentContext > & ctx )
    :
    m_xNextContext( ctx ),
    m_bShowErrorsOnce(false),
    m_aRefCount(0)
{
}

JavaContext::JavaContext( const Reference< XCurrentContext > & ctx,
                          bool bShowErrorsOnce)
    : m_xNextContext( ctx ), m_bShowErrorsOnce(bShowErrorsOnce),
      m_aRefCount(0)
{
}

Any SAL_CALL JavaContext::queryInterface(const Type& aType )
    throw (RuntimeException)
{
    if (aType == getCppuType(reinterpret_cast<Reference<XInterface>*>(0)))
        return Any( static_cast<XInterface*>(this), aType);
    else if (aType == getCppuType(reinterpret_cast<Reference<XCurrentContext>*>(0)))
        return Any( static_cast<XCurrentContext*>(this), aType);
    return Any();
}

void SAL_CALL JavaContext::acquire(  ) throw ()
{
    osl_incrementInterlockedCount( &m_aRefCount );
}

void SAL_CALL JavaContext::release(  ) throw ()
{
    if (! osl_decrementInterlockedCount( &m_aRefCount ))
        delete this;
}

Any SAL_CALL JavaContext::getValueByName( const OUString& Name) throw (RuntimeException)
{
    Any retVal;

    if ( 0 == Name.compareToAscii( JAVA_INTERACTION_HANDLER_NAME ))
    {
        {
            osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
            if (!m_xHandler.is())
                m_xHandler = Reference< XInteractionHandler >(
                    new JavaInteractionHandler(m_bShowErrorsOnce));
        }
        retVal = makeAny(m_xHandler);

    }
    else if( m_xNextContext.is() )
    {
        // Call next context in chain if found
        retVal = m_xNextContext->getValueByName( Name );
    }
    return retVal;
}

}
<commit_msg>INTEGRATION: CWS warnings01 (1.3.62); FILE MERGED 2005/10/25 15:07:40 pl 1.3.62.1: #i55991# removed warnings for linux platform<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: javacontext.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 21:18:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include "com/sun/star/uno/Any.hxx"
#endif
#ifndef _COM_SUN_STAR_UNO_TYPE_HXX_
#include "com/sun/star/uno/Type.hxx"
#endif
#ifndef _SVTOOLS_SVTDATA_HXX
#include "svtdata.hxx"
#endif
#ifndef _SVTOOLS_JAVACONTEXT_HXX_
#include "javacontext.hxx"
#endif
#ifndef _SVTOOLS_JAVAINTERACTION_HXX_
#include "javainteractionhandler.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::task;
namespace svt
{

JavaContext::JavaContext( const Reference< XCurrentContext > & ctx )
    :
    m_aRefCount(0),
    m_xNextContext( ctx ),
    m_bShowErrorsOnce(false)
{
}

JavaContext::JavaContext( const Reference< XCurrentContext > & ctx,
                          bool bShowErrorsOnce)
    : m_aRefCount(0),
      m_xNextContext( ctx ),
      m_bShowErrorsOnce(bShowErrorsOnce)
{
}

JavaContext::~JavaContext()
{
}

Any SAL_CALL JavaContext::queryInterface(const Type& aType )
    throw (RuntimeException)
{
    if (aType == getCppuType(reinterpret_cast<Reference<XInterface>*>(0)))
        return Any( static_cast<XInterface*>(this), aType);
    else if (aType == getCppuType(reinterpret_cast<Reference<XCurrentContext>*>(0)))
        return Any( static_cast<XCurrentContext*>(this), aType);
    return Any();
}

void SAL_CALL JavaContext::acquire(  ) throw ()
{
    osl_incrementInterlockedCount( &m_aRefCount );
}

void SAL_CALL JavaContext::release(  ) throw ()
{
    if (! osl_decrementInterlockedCount( &m_aRefCount ))
        delete this;
}

Any SAL_CALL JavaContext::getValueByName( const OUString& Name) throw (RuntimeException)
{
    Any retVal;

    if ( 0 == Name.compareToAscii( JAVA_INTERACTION_HANDLER_NAME ))
    {
        {
            osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
            if (!m_xHandler.is())
                m_xHandler = Reference< XInteractionHandler >(
                    new JavaInteractionHandler(m_bShowErrorsOnce));
        }
        retVal = makeAny(m_xHandler);

    }
    else if( m_xNextContext.is() )
    {
        // Call next context in chain if found
        retVal = m_xNextContext->getValueByName( Name );
    }
    return retVal;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: commtest.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 15:22:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef _SV_SVAPP_HXX //autogen wg. Application
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_WRKWIN_HXX //autogen wg. WorkWindow
#include <vcl/wrkwin.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX //autogen wg. ToolBox
#include <vcl/toolbox.hxx>
#endif

#ifndef _SIMPLECM_HXX //autogen wg. CommunicationManager
#include <tools/simplecm.hxx>
#endif
#ifndef _COMMUNI_HXX //autogen
#include "communi.hxx"
#endif
#include "brooker.hxx"
//#include <tools/bcst.hxx>

#include "commtest.hrc"

#define TCP_PORT 17612

#define CUniString( constAsciiStr ) UniString( RTL_CONSTASCII_USTRINGPARAM ( constAsciiStr ) )

class PacketSender : public Timer
{
    SvStream* mpData;
    CommunicationLinkRef mxCL;

public:
    PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL );
    virtual void    Timeout();
};

PacketSender::PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL )
: mpData( pData )
, mxCL( pCL )
{
    SetTimeout( nDelay );
    Start();
}

void PacketSender::Timeout()
{
    mxCL->TransferDataStream( mpData );
    delete mpData;
    delete this;
}

class DelayedDeleter : public Timer
{
    CommunicationManager *mpManager;

public:
    DelayedDeleter( ULONG nDelay, CommunicationManager *pManager );
    virtual void    Timeout();
};

DelayedDeleter::DelayedDeleter( ULONG nDelay, CommunicationManager *pManager )
: mpManager( pManager )
{
    SetTimeout( nDelay );
    Start();
}

void DelayedDeleter::Timeout()
{
    delete mpManager;
    delete this;
}

class CommunicationTester : public Application
{
    DECL_LINK( TBClick, ToolBox* );
    DECL_LINK( DataReceived, CommunicationLink* );
    DECL_LINK( ConnectionOpened, CommunicationLink* );
    DECL_LINK( ConnectionClosed, CommunicationLink* );

    CommunicationManager *pClientTcp, *pServerTcp;
    InformationBroadcaster *pBCSTSend;
    InformationBroadcaster *pBCSTListen;
    InformationBrooker *pBCSTBrooker;
public:
    CommunicationTester();

    virtual void Main();
};

CommunicationTester IchSelber;

CommunicationTester::CommunicationTester()
: pClientTcp( NULL )
, pServerTcp( NULL )
, pBCSTSend( NULL )
, pBCSTListen( NULL )
, pBCSTBrooker( NULL )
{}

void CommunicationTester::Main()
{
    ResMgr *pRes = ResMgr::CreateResMgr( "commtest" );
    Resource::SetResManager( pRes );
    WorkWindow aWW( NULL, WB_APP | WB_STDWORK );
    aWW.Show();
    ToolBox aTB( &aWW, ResId( TBMenu ) );
    aTB.Show();
    aTB.RecalcItems();
    aTB.SetFloatingMode( TRUE );
    aTB.SetFloatingMode( FALSE );
    aTB.SetClickHdl( LINK( this, CommunicationTester, TBClick ) );

    Execute();
}

#define SWITCH( pManager, ManagerClass )                    \
{                                                           \
    if ( pManager )                                         \
    {                                                       \
        pManager->StopCommunication();                      \
        new DelayedDeleter( 1000, pManager );               \
        pTB->SetItemState( pTB->GetCurItemId(), STATE_NOCHECK );    \
        pManager = NULL;                                    \
    }                                                       \
    else                                                    \
    {                                                       \
        pManager = new ManagerClass;                        \
        pManager->SetConnectionOpenedHdl( LINK( this, CommunicationTester, ConnectionOpened ) );\
        pManager->SetConnectionClosedHdl( LINK( this, CommunicationTester, ConnectionClosed ) );\
        pManager->SetDataReceivedHdl( LINK( this, CommunicationTester, DataReceived ) );\
        pTB->SetItemState( pTB->GetCurItemId(), STATE_CHECK );  \
    }                                                       \
}

IMPL_LINK( CommunicationTester, TBClick, ToolBox*, pTB )
{
    switch ( pTB->GetCurItemId() )
    {
        case SERVER_TCP:
            {
                SWITCH( pServerTcp, CommunicationManagerServerViaSocket( TCP_PORT, (USHORT) 32000 ) );
                if ( pServerTcp )
                    pServerTcp->StartCommunication();   // Am Port horchen
            }
            break;
        case CLIENT_TCP:
            {
                SWITCH( pClientTcp, CommunicationManagerClientViaSocket( "localhost", TCP_PORT ) );
                if ( pClientTcp )
                    pClientTcp->StartCommunication();   // Eine Verbindung aufbauen
            }
            break;
        case BCST_BROOKER:
            {
                if ( pBCSTBrooker )
                {
                    delete pBCSTBrooker;
                    pBCSTBrooker = NULL;
                }
                else
                {
                    pBCSTBrooker = new InformationBrooker();
                }
            }
            break;
        case BCST_LISTEN:
            {
                if ( pBCSTListen )
                {
                    delete pBCSTListen;
                    pBCSTListen = NULL;
                }
                else
                {
                    pBCSTListen = new InformationBroadcaster();
                }
            }
        case BCST_SEND:
            {
                if ( pBCSTSend )
                {
                    pBCSTSend->Broadcast( BCST_CAT_PL2X,      "Message: BCST_CAT_PL2X" );
                    pBCSTSend->Broadcast( BCST_CAT_MINORCOPY, "Message: BCST_CAT_MINORCOPY" );
                    pBCSTSend->Broadcast( BCST_CAT_DELIVER,   "Message: BCST_CAT_DELIVER" );
                    pBCSTSend->Broadcast( BCST_CAT_ALL,       "Message: BCST_CAT_ALL" );
                }
                else
                {
                    pBCSTSend = new InformationBroadcaster();
                }
            }
            break;
    }
    return 0;
}

IMPL_LINK( CommunicationTester, ConnectionOpened, CommunicationLink*, pCL )
{
    SvStream *pData = pCL->GetBestCommunicationStream();
    while ( pData->Tell() < 70 ) *pData << 123;

    pCL->TransferDataStream( pData );
    return 0;
}

IMPL_LINK( CommunicationTester, ConnectionClosed, CommunicationLink*, pCL )
{
    return 0;
}

IMPL_LINK( CommunicationTester, DataReceived, CommunicationLink*, pCL )
{
    // Find Manager
    CommunicationManager* pManager;
    if ( pClientTcp && pClientTcp->IsLinkValid( pCL ) )
    {
        pManager = pClientTcp;
    }
    if ( pServerTcp && pServerTcp->IsLinkValid( pCL ) )
    {
        DBG_ASSERT( !pManager, "CommunicationLink bei mehreren Managern eingetragen");
        pManager = pServerTcp;
    }
    DBG_ASSERT( pCL->GetCommunicationManager() == pManager, "Manager des Link != Manager bei dem der Link Valid ist");

    // Send Data Back (Echo)
    new PacketSender( 1000, pCL->GetServiceData(), pCL );

    return 0;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.5.450); FILE MERGED 2008/04/01 15:45:26 thb 1.5.450.2: #i85898# Stripping all external header guards 2008/03/31 13:02:27 rt 1.5.450.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: commtest.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/toolbox.hxx>

#include <tools/simplecm.hxx>
#include "communi.hxx"
#include "brooker.hxx"
//#include <tools/bcst.hxx>

#include "commtest.hrc"

#define TCP_PORT 17612

#define CUniString( constAsciiStr ) UniString( RTL_CONSTASCII_USTRINGPARAM ( constAsciiStr ) )

class PacketSender : public Timer
{
    SvStream* mpData;
    CommunicationLinkRef mxCL;

public:
    PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL );
    virtual void    Timeout();
};

PacketSender::PacketSender( ULONG nDelay, SvStream* pData, CommunicationLink* pCL )
: mpData( pData )
, mxCL( pCL )
{
    SetTimeout( nDelay );
    Start();
}

void PacketSender::Timeout()
{
    mxCL->TransferDataStream( mpData );
    delete mpData;
    delete this;
}

class DelayedDeleter : public Timer
{
    CommunicationManager *mpManager;

public:
    DelayedDeleter( ULONG nDelay, CommunicationManager *pManager );
    virtual void    Timeout();
};

DelayedDeleter::DelayedDeleter( ULONG nDelay, CommunicationManager *pManager )
: mpManager( pManager )
{
    SetTimeout( nDelay );
    Start();
}

void DelayedDeleter::Timeout()
{
    delete mpManager;
    delete this;
}

class CommunicationTester : public Application
{
    DECL_LINK( TBClick, ToolBox* );
    DECL_LINK( DataReceived, CommunicationLink* );
    DECL_LINK( ConnectionOpened, CommunicationLink* );
    DECL_LINK( ConnectionClosed, CommunicationLink* );

    CommunicationManager *pClientTcp, *pServerTcp;
    InformationBroadcaster *pBCSTSend;
    InformationBroadcaster *pBCSTListen;
    InformationBrooker *pBCSTBrooker;
public:
    CommunicationTester();

    virtual void Main();
};

CommunicationTester IchSelber;

CommunicationTester::CommunicationTester()
: pClientTcp( NULL )
, pServerTcp( NULL )
, pBCSTSend( NULL )
, pBCSTListen( NULL )
, pBCSTBrooker( NULL )
{}

void CommunicationTester::Main()
{
    ResMgr *pRes = ResMgr::CreateResMgr( "commtest" );
    Resource::SetResManager( pRes );
    WorkWindow aWW( NULL, WB_APP | WB_STDWORK );
    aWW.Show();
    ToolBox aTB( &aWW, ResId( TBMenu ) );
    aTB.Show();
    aTB.RecalcItems();
    aTB.SetFloatingMode( TRUE );
    aTB.SetFloatingMode( FALSE );
    aTB.SetClickHdl( LINK( this, CommunicationTester, TBClick ) );

    Execute();
}

#define SWITCH( pManager, ManagerClass )                    \
{                                                           \
    if ( pManager )                                         \
    {                                                       \
        pManager->StopCommunication();                      \
        new DelayedDeleter( 1000, pManager );               \
        pTB->SetItemState( pTB->GetCurItemId(), STATE_NOCHECK );    \
        pManager = NULL;                                    \
    }                                                       \
    else                                                    \
    {                                                       \
        pManager = new ManagerClass;                        \
        pManager->SetConnectionOpenedHdl( LINK( this, CommunicationTester, ConnectionOpened ) );\
        pManager->SetConnectionClosedHdl( LINK( this, CommunicationTester, ConnectionClosed ) );\
        pManager->SetDataReceivedHdl( LINK( this, CommunicationTester, DataReceived ) );\
        pTB->SetItemState( pTB->GetCurItemId(), STATE_CHECK );  \
    }                                                       \
}

IMPL_LINK( CommunicationTester, TBClick, ToolBox*, pTB )
{
    switch ( pTB->GetCurItemId() )
    {
        case SERVER_TCP:
            {
                SWITCH( pServerTcp, CommunicationManagerServerViaSocket( TCP_PORT, (USHORT) 32000 ) );
                if ( pServerTcp )
                    pServerTcp->StartCommunication();   // Am Port horchen
            }
            break;
        case CLIENT_TCP:
            {
                SWITCH( pClientTcp, CommunicationManagerClientViaSocket( "localhost", TCP_PORT ) );
                if ( pClientTcp )
                    pClientTcp->StartCommunication();   // Eine Verbindung aufbauen
            }
            break;
        case BCST_BROOKER:
            {
                if ( pBCSTBrooker )
                {
                    delete pBCSTBrooker;
                    pBCSTBrooker = NULL;
                }
                else
                {
                    pBCSTBrooker = new InformationBrooker();
                }
            }
            break;
        case BCST_LISTEN:
            {
                if ( pBCSTListen )
                {
                    delete pBCSTListen;
                    pBCSTListen = NULL;
                }
                else
                {
                    pBCSTListen = new InformationBroadcaster();
                }
            }
        case BCST_SEND:
            {
                if ( pBCSTSend )
                {
                    pBCSTSend->Broadcast( BCST_CAT_PL2X,      "Message: BCST_CAT_PL2X" );
                    pBCSTSend->Broadcast( BCST_CAT_MINORCOPY, "Message: BCST_CAT_MINORCOPY" );
                    pBCSTSend->Broadcast( BCST_CAT_DELIVER,   "Message: BCST_CAT_DELIVER" );
                    pBCSTSend->Broadcast( BCST_CAT_ALL,       "Message: BCST_CAT_ALL" );
                }
                else
                {
                    pBCSTSend = new InformationBroadcaster();
                }
            }
            break;
    }
    return 0;
}

IMPL_LINK( CommunicationTester, ConnectionOpened, CommunicationLink*, pCL )
{
    SvStream *pData = pCL->GetBestCommunicationStream();
    while ( pData->Tell() < 70 ) *pData << 123;

    pCL->TransferDataStream( pData );
    return 0;
}

IMPL_LINK( CommunicationTester, ConnectionClosed, CommunicationLink*, pCL )
{
    return 0;
}

IMPL_LINK( CommunicationTester, DataReceived, CommunicationLink*, pCL )
{
    // Find Manager
    CommunicationManager* pManager;
    if ( pClientTcp && pClientTcp->IsLinkValid( pCL ) )
    {
        pManager = pClientTcp;
    }
    if ( pServerTcp && pServerTcp->IsLinkValid( pCL ) )
    {
        DBG_ASSERT( !pManager, "CommunicationLink bei mehreren Managern eingetragen");
        pManager = pServerTcp;
    }
    DBG_ASSERT( pCL->GetCommunicationManager() == pManager, "Manager des Link != Manager bei dem der Link Valid ist");

    // Send Data Back (Echo)
    new PacketSender( 1000, pCL->GetServiceData(), pCL );

    return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: accfrmobj.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: mib $ $Date: 2002-08-07 12:41:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ACCFRMOBJ_HXX
#define _ACCFRMOBJ_HXX

#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif
#ifndef _CELLFRM_HXX
#include <cellfrm.hxx>
#endif
#ifndef _PAGEFRM_HXX
#include <pagefrm.hxx>
#endif
#ifndef _DFLYOBJ_HXX
#include <dflyobj.hxx>
#endif
#ifndef _SWTABLE_HXX
#include <swtable.hxx>
#endif

class SwFrmOrObj
{
    const SdrObject *pObj;
    const SwFrm *pFrm;

    inline void Init( const SdrObject *pO );
    inline void Init( const SwFrm *pF );

public:

    inline SwFrmOrObj();
    inline SwFrmOrObj( const SdrObject *pO );
    inline SwFrmOrObj( const SwFrm *pF );
    inline SwFrmOrObj( const SwFrm *pF, const SdrObject *pO );
    inline SwFrmOrObj( const SwFrmOrObj& r );

    inline SwFrmOrObj& operator=( const SwFrmOrObj& r );
    inline SwFrmOrObj& operator=( const SdrObject *pO );
    inline SwFrmOrObj& operator=( const SwFrm *pF );

    inline sal_Bool operator==( const SwFrmOrObj& r ) const;
    inline sal_Bool operator==( const SdrObject *pO ) const;
    inline sal_Bool operator==( const SwFrm *pF ) const;

    inline sal_Bool IsValid() const;

    inline const SdrObject *GetSdrObject() const;
    inline const SwFrm *GetSwFrm() const;

    inline sal_Bool IsAccessible( sal_Bool bPagePreview ) const;
    sal_Bool IsBoundAsChar() const;
    inline sal_Bool IsVisibleChildrenOnly() const;
    inline SwRect GetBox() const;
    inline SwRect GetBounds() const;
};

inline void SwFrmOrObj::Init( const SdrObject *pO )
{
    pObj = pO;
    pFrm = pObj && pObj->IsWriterFlyFrame()
                ? static_cast < const SwVirtFlyDrawObj * >( pObj )->GetFlyFrm()
                : 0;
}

inline void SwFrmOrObj::Init( const SwFrm *pF )
{
    pFrm = pF;
    pObj = pFrm && pFrm->IsFlyFrm()
                ? static_cast < const SwFlyFrm * >( pFrm )->GetVirtDrawObj()
                : 0;
}

inline SwFrmOrObj::SwFrmOrObj() :
    pObj( 0 ), pFrm( 0 )
{}

inline SwFrmOrObj::SwFrmOrObj( const SdrObject *pO )
{
    Init( pO );
}

inline SwFrmOrObj::SwFrmOrObj( const SwFrm *pF )
{
    Init( pF );
}

inline SwFrmOrObj::SwFrmOrObj( const SwFrm *pF, const SdrObject *pO )
{
    if( pF )
        Init( pF );
    else
        Init( pO );
    ASSERT( (!pF || pF == pFrm) && (!pO || pO == pObj),
            "invalid frame/object combination" );

}

inline SwFrmOrObj::SwFrmOrObj( const SwFrmOrObj& r ) :
    pObj( r.pObj ), pFrm( r.pFrm )
{}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SwFrmOrObj& r )
{
    pObj = r.pObj;
    pFrm = r.pFrm;
    return *this;
}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SdrObject *pO )
{
    Init( pO );
    return *this;
}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SwFrm *pF )
{
    Init( pF );
    return *this;
}

inline sal_Bool SwFrmOrObj::operator==( const SwFrmOrObj& r ) const
{
    return pObj == r.pObj && pFrm == r.pFrm;
}

inline sal_Bool SwFrmOrObj::operator==( const SdrObject *pO ) const
{
    return pObj == pO;
}

inline sal_Bool SwFrmOrObj::operator==( const SwFrm *pF ) const
{
    return pFrm == pF;
}

inline sal_Bool SwFrmOrObj::IsValid() const
{
    return pObj != 0 || pFrm != 0;
}

inline const SdrObject *SwFrmOrObj::GetSdrObject() const
{
    return pObj;
}

inline const SwFrm *SwFrmOrObj::GetSwFrm() const
{
    return pFrm;
}

inline sal_Bool SwFrmOrObj::IsAccessible( sal_Bool bPagePreview ) const
{
    return ( pFrm && pFrm->IsAccessibleFrm() &&
             ( !pFrm->IsCellFrm() ||
              static_cast<const SwCellFrm *>( pFrm )->GetTabBox()
                                                     ->GetSttNd() != 0 ) &&
             ( bPagePreview || !pFrm->IsPageFrm() ) ) ||
           pObj;
}

inline sal_Bool SwFrmOrObj::IsVisibleChildrenOnly() const
{
    return !pFrm ||
           !( pFrm->IsTabFrm() || pFrm->IsInTab() ||
             (IsBoundAsChar() &&
              static_cast< const SwFlyFrm *>(pFrm)->GetAnchor()->IsInTab()) );
}

inline SwRect SwFrmOrObj::GetBox() const
{
    if( pFrm )
    {
        if( pFrm->IsPageFrm() &&
            static_cast< const SwPageFrm * >( pFrm )->IsEmptyPage() )
        {
            SwRect aBox( pFrm->Frm().Left(), pFrm->Frm().Top()-1, 1, 1 );
            return aBox;
        }
        else
            return pFrm->Frm();
    }
    else if( pObj )
        return SwRect( pObj->GetBoundRect() );
    else
        return SwRect();

}

inline SwRect SwFrmOrObj::GetBounds() const
{
    if( pFrm )
    {
        if( pFrm->IsPageFrm() &&
            static_cast< const SwPageFrm * >( pFrm )->IsEmptyPage() )
        {
            SwRect aBox( pFrm->Frm().Left(), pFrm->Frm().Top()-1, 0, 0 );
            return aBox;
        }
        else
            return pFrm->PaintArea();
    }
    else if( pObj )
        return SwRect( pObj->GetBoundRect() );
}

#endif
<commit_msg>INTEGRATION: CWS sw008 (1.7.120); FILE MERGED 2003/03/12 17:19:43 dvo 1.7.120.1: #108069# 'cut' tab frames so they are always contained within their parents<commit_after>/*************************************************************************
 *
 *  $RCSfile: accfrmobj.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-01 15:28:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _ACCFRMOBJ_HXX
#define _ACCFRMOBJ_HXX

#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif
#ifndef _CELLFRM_HXX
#include <cellfrm.hxx>
#endif
#ifndef _PAGEFRM_HXX
#include <pagefrm.hxx>
#endif
#ifndef _DFLYOBJ_HXX
#include <dflyobj.hxx>
#endif
#ifndef _SWTABLE_HXX
#include <swtable.hxx>
#endif

class SwFrmOrObj
{
    const SdrObject *pObj;
    const SwFrm *pFrm;

    inline void Init( const SdrObject *pO );
    inline void Init( const SwFrm *pF );

public:

    inline SwFrmOrObj();
    inline SwFrmOrObj( const SdrObject *pO );
    inline SwFrmOrObj( const SwFrm *pF );
    inline SwFrmOrObj( const SwFrm *pF, const SdrObject *pO );
    inline SwFrmOrObj( const SwFrmOrObj& r );

    inline SwFrmOrObj& operator=( const SwFrmOrObj& r );
    inline SwFrmOrObj& operator=( const SdrObject *pO );
    inline SwFrmOrObj& operator=( const SwFrm *pF );

    inline sal_Bool operator==( const SwFrmOrObj& r ) const;
    inline sal_Bool operator==( const SdrObject *pO ) const;
    inline sal_Bool operator==( const SwFrm *pF ) const;

    inline sal_Bool IsValid() const;

    inline const SdrObject *GetSdrObject() const;
    inline const SwFrm *GetSwFrm() const;

    inline sal_Bool IsAccessible( sal_Bool bPagePreview ) const;
    sal_Bool IsBoundAsChar() const;
    inline sal_Bool IsVisibleChildrenOnly() const;
    inline SwRect GetBox() const;
    inline SwRect GetBounds() const;
};

inline void SwFrmOrObj::Init( const SdrObject *pO )
{
    pObj = pO;
    pFrm = pObj && pObj->IsWriterFlyFrame()
                ? static_cast < const SwVirtFlyDrawObj * >( pObj )->GetFlyFrm()
                : 0;
}

inline void SwFrmOrObj::Init( const SwFrm *pF )
{
    pFrm = pF;
    pObj = pFrm && pFrm->IsFlyFrm()
                ? static_cast < const SwFlyFrm * >( pFrm )->GetVirtDrawObj()
                : 0;
}

inline SwFrmOrObj::SwFrmOrObj() :
    pObj( 0 ), pFrm( 0 )
{}

inline SwFrmOrObj::SwFrmOrObj( const SdrObject *pO )
{
    Init( pO );
}

inline SwFrmOrObj::SwFrmOrObj( const SwFrm *pF )
{
    Init( pF );
}

inline SwFrmOrObj::SwFrmOrObj( const SwFrm *pF, const SdrObject *pO )
{
    if( pF )
        Init( pF );
    else
        Init( pO );
    ASSERT( (!pF || pF == pFrm) && (!pO || pO == pObj),
            "invalid frame/object combination" );

}

inline SwFrmOrObj::SwFrmOrObj( const SwFrmOrObj& r ) :
    pObj( r.pObj ), pFrm( r.pFrm )
{}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SwFrmOrObj& r )
{
    pObj = r.pObj;
    pFrm = r.pFrm;
    return *this;
}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SdrObject *pO )
{
    Init( pO );
    return *this;
}

inline SwFrmOrObj& SwFrmOrObj::operator=( const SwFrm *pF )
{
    Init( pF );
    return *this;
}

inline sal_Bool SwFrmOrObj::operator==( const SwFrmOrObj& r ) const
{
    return pObj == r.pObj && pFrm == r.pFrm;
}

inline sal_Bool SwFrmOrObj::operator==( const SdrObject *pO ) const
{
    return pObj == pO;
}

inline sal_Bool SwFrmOrObj::operator==( const SwFrm *pF ) const
{
    return pFrm == pF;
}

inline sal_Bool SwFrmOrObj::IsValid() const
{
    return pObj != 0 || pFrm != 0;
}

inline const SdrObject *SwFrmOrObj::GetSdrObject() const
{
    return pObj;
}

inline const SwFrm *SwFrmOrObj::GetSwFrm() const
{
    return pFrm;
}

inline sal_Bool SwFrmOrObj::IsAccessible( sal_Bool bPagePreview ) const
{
    return ( pFrm && pFrm->IsAccessibleFrm() &&
             ( !pFrm->IsCellFrm() ||
              static_cast<const SwCellFrm *>( pFrm )->GetTabBox()
                                                     ->GetSttNd() != 0 ) &&
             ( bPagePreview || !pFrm->IsPageFrm() ) ) ||
           pObj;
}

inline sal_Bool SwFrmOrObj::IsVisibleChildrenOnly() const
{
    return !pFrm ||
           !( pFrm->IsTabFrm() || pFrm->IsInTab() ||
             (IsBoundAsChar() &&
              static_cast< const SwFlyFrm *>(pFrm)->GetAnchor()->IsInTab()) );
}

inline SwRect SwFrmOrObj::GetBox() const
{
    if( pFrm )
    {
        if( pFrm->IsPageFrm() &&
            static_cast< const SwPageFrm * >( pFrm )->IsEmptyPage() )
        {
            SwRect aBox( pFrm->Frm().Left(), pFrm->Frm().Top()-1, 1, 1 );
            return aBox;
        }
        else if ( pFrm->IsTabFrm() )
        {
            SwRect aBox( pFrm->Frm() );
            aBox.Intersection( pFrm->GetUpper()->Frm() );
            return aBox;
        }
        else
            return pFrm->Frm();
    }
    else if( pObj )
        return SwRect( pObj->GetBoundRect() );
    else
        return SwRect();

}

inline SwRect SwFrmOrObj::GetBounds() const
{
    if( pFrm )
    {
        if( pFrm->IsPageFrm() &&
            static_cast< const SwPageFrm * >( pFrm )->IsEmptyPage() )
        {
            SwRect aBox( pFrm->Frm().Left(), pFrm->Frm().Top()-1, 0, 0 );
            return aBox;
        }
        else
            return pFrm->PaintArea();
    }
    else if( pObj )
        return SwRect( pObj->GetBoundRect() );
}

#endif
<|endoftext|>


<commit_before><commit_msg>WaE: maybe-uninitialized<commit_after><|endoftext|>


<commit_before>#include "Record.h"
#include "CodeEmitterGen.h"
#include <ostream>

void CodeEmitterGen::createEmitter(std::ostream &o) {
  std::vector<Record*> Insts;

  const std::map<std::string, Record*> &Defs = Records.getDefs();
  Record *Inst = Records.getClass("Instruction");
  assert(Inst && "Couldn't find Instruction class!");

  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
	 E = Defs.end(); I != E; ++I)
    if (I->second->isSubClassOf(Inst))
      Insts.push_back(I->second);

  std::string Namespace = "V9::";
  std::string ClassName = "SparcV9CodeEmitter::";

  //const std::string &Namespace = Inst->getValue("Namespace")->getName();
  o << "unsigned " << ClassName
    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
    << "  unsigned Value = 0;\n"
    << "  std::cerr << MI;\n"
    << "  switch (MI.getOpcode()) {\n";
  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
       I != E; ++I)
  {
    Record *R = *I;
    o << "    case " << Namespace << R->getName() << ": {\n"
      << "      std::cerr << \"Emitting " << R->getName() << "\\n\";\n";

    const RecordVal *InstVal = R->getValue("Inst");
    Init *InitVal = InstVal->getValue();

    assert(dynamic_cast<BitsInit*>(InitVal) &&
           "Can only handle undefined bits<> types!");
    BitsInit *BI = (BitsInit*)InitVal;

    unsigned Value = 0;
    const std::vector<RecordVal> &Vals = R->getValues();

    o << "      // prefilling: ";
    // Start by filling in fixed values...
    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
        Value |= B->getValue() << (e-i-1);
        o << B->getValue();
      } else {
        o << "0";
      }
    }
    o << "\n";

    o << "      // " << *InstVal << "\n";
    o << "      Value = " << Value << "U;\n\n";

    // Loop over all of the fields in the instruction adding in any
    // contributions to this value (due to bit references).
    //
    unsigned op = 0;
    std::map<const std::string,unsigned> OpOrder;
    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
      if (Vals[i].getName() != "Inst" &&
          !Vals[i].getValue()->isComplete() &&
          Vals[i].getName() != "annul" &&
          Vals[i].getName() != "cc" &&
          Vals[i].getName() != "predict")
      {
        o << "      // op" << op << ": " << Vals[i].getName() << "\n"
          << "      int64_t op" << op
          <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
        //<< "      MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
        OpOrder[Vals[i].getName()] = op++;
      }
    }

    unsigned Offset = 31;
    for (int f = Vals.size()-1; f >= 0; --f) {
      if (Vals[f].getPrefix()) {
        BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();

        // Scan through the field looking for bit initializers of the current
        // variable...
        for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
          if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){
            --Offset;
          } else if (UnsetInit *UI =
                     dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
            --Offset;
          } else if (VarBitInit *VBI =
                     dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
                << ", " << VBI->getBitNum()
                << ")" << " << " << Offset << ";\n";
              --Offset;
            } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
              // FIXME: implement this!
              o << "FIELD INIT not implemented yet!\n";
            } else {
              o << "Error: UNIMPLEMENTED\n";
            }
          }
        }
      } else {
        if (Vals[f].getName() == "annul" || Vals[f].getName() == "predict")
          --Offset;
      }
    }

    o << "      break;\n"
      << "    }\n";
  }
  o << "  default:\n"
    << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
    << "    abort();\n"
    << "  }\n"
    << "  return Value;\n"
    << "}\n";
}
<commit_msg>* Stop ignoring cc registers, since we actually use them in branches. * Added comment as to why we are still ignoring predict and annul bits.<commit_after>#include "Record.h"
#include "CodeEmitterGen.h"
#include <ostream>

void CodeEmitterGen::createEmitter(std::ostream &o) {
  std::vector<Record*> Insts;

  const std::map<std::string, Record*> &Defs = Records.getDefs();
  Record *Inst = Records.getClass("Instruction");
  assert(Inst && "Couldn't find Instruction class!");

  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
	 E = Defs.end(); I != E; ++I)
    if (I->second->isSubClassOf(Inst))
      Insts.push_back(I->second);

  std::string Namespace = "V9::";
  std::string ClassName = "SparcV9CodeEmitter::";

  //const std::string &Namespace = Inst->getValue("Namespace")->getName();
  o << "unsigned " << ClassName
    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
    << "  unsigned Value = 0;\n"
    << "  std::cerr << MI;\n"
    << "  switch (MI.getOpcode()) {\n";
  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
       I != E; ++I)
  {
    Record *R = *I;
    o << "    case " << Namespace << R->getName() << ": {\n"
      << "      std::cerr << \"Emitting " << R->getName() << "\\n\";\n";

    const RecordVal *InstVal = R->getValue("Inst");
    Init *InitVal = InstVal->getValue();

    assert(dynamic_cast<BitsInit*>(InitVal) &&
           "Can only handle undefined bits<> types!");
    BitsInit *BI = (BitsInit*)InitVal;

    unsigned Value = 0;
    const std::vector<RecordVal> &Vals = R->getValues();

    o << "      // prefilling: ";
    // Start by filling in fixed values...
    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
        Value |= B->getValue() << (e-i-1);
        o << B->getValue();
      } else {
        o << "0";
      }
    }
    o << "\n";

    o << "      // " << *InstVal << "\n";
    o << "      Value = " << Value << "U;\n\n";

    // Loop over all of the fields in the instruction adding in any
    // contributions to this value (due to bit references).
    //
    unsigned op = 0;
    std::map<const std::string,unsigned> OpOrder;
    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
      if (Vals[i].getName() != "Inst" &&
          !Vals[i].getValue()->isComplete() &&
          /* ignore annul and predict bits since no one sets them yet */
          Vals[i].getName() != "annul" &&
          Vals[i].getName() != "predict")
      {
        o << "      // op" << op << ": " << Vals[i].getName() << "\n"
          << "      int64_t op" << op
          <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
        //<< "      MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
        OpOrder[Vals[i].getName()] = op++;
      }
    }

    unsigned Offset = 31;
    for (int f = Vals.size()-1; f >= 0; --f) {
      if (Vals[f].getPrefix()) {
        BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();

        // Scan through the field looking for bit initializers of the current
        // variable...
        for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
          if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){
            --Offset;
          } else if (UnsetInit *UI =
                     dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
            --Offset;
          } else if (VarBitInit *VBI =
                     dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
                << ", " << VBI->getBitNum()
                << ")" << " << " << Offset << ";\n";
              --Offset;
            } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
              // FIXME: implement this!
              o << "FIELD INIT not implemented yet!\n";
            } else {
              o << "Error: UNIMPLEMENTED\n";
            }
          }
        }
      } else {
        // ignore annul and predict bits since no one sets them yet
        if (Vals[f].getName() == "annul" || Vals[f].getName() == "predict")
          --Offset;
      }
    }

    o << "      break;\n"
      << "    }\n";
  }
  o << "  default:\n"
    << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
    << "    abort();\n"
    << "  }\n"
    << "  return Value;\n"
    << "}\n";
}
<|endoftext|>


<commit_before>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

#define VERBOSE(x) x
#define VERBOSE2(x)

#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif

#include <boost/foreach.hpp>

#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#include "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/QueryEdge.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Util/GraphLoader.h"

using namespace std;

typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef BaseConfiguration ContractorConfiguration;

std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;

int main (int argc, char *argv[]) {
    if(argc < 3) {
        ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
    }
    std::string SRTM_ROOT;

    INFO("Using restrictions from file: " << argv[2]);
    std::ifstream restrictionsInstream(argv[2], ios::binary);
    if(!restrictionsInstream.good()) {
        ERR("Could not access <osrm-restrictions> files");
    }
    _Restriction restriction;
    unsigned usableRestrictionsCounter(0);
    restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
    inputRestrictions.resize(usableRestrictionsCounter);
    restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction));
    restrictionsInstream.close();

    std::ifstream in;
    in.open (argv[1], std::ifstream::in | std::ifstream::binary);
    if (!in.is_open()) {
        ERR("Cannot open " << argv[1]);
    }

    std::vector<ImportEdge> edgeList;
    NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
    in.close();
    INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");

    /***
     * Building an edge-expanded graph from node-based input an turn restrictions
     */

    INFO("Starting SCC graph traversal");
    TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping);
    std::vector<ImportEdge>().swap(edgeList);
    tarjan->Run();
    std::vector<_Restriction>().swap(inputRestrictions);
    std::vector<NodeID>().swap(bollardNodes);
    std::vector<NodeID>().swap(trafficLightNodes);
    INFO("finished component analysis");
    return 0;
}
<commit_msg>Adding include<commit_after>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

#define VERBOSE(x) x
#define VERBOSE2(x)

#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif

#include <boost/foreach.hpp>

#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#include "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Util/GraphLoader.h"

using namespace std;

typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef BaseConfiguration ContractorConfiguration;

std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;

int main (int argc, char *argv[]) {
    if(argc < 3) {
        ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
    }
    std::string SRTM_ROOT;

    INFO("Using restrictions from file: " << argv[2]);
    std::ifstream restrictionsInstream(argv[2], ios::binary);
    if(!restrictionsInstream.good()) {
        ERR("Could not access <osrm-restrictions> files");
    }
    _Restriction restriction;
    unsigned usableRestrictionsCounter(0);
    restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
    inputRestrictions.resize(usableRestrictionsCounter);
    restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction));
    restrictionsInstream.close();

    std::ifstream in;
    in.open (argv[1], std::ifstream::in | std::ifstream::binary);
    if (!in.is_open()) {
        ERR("Cannot open " << argv[1]);
    }

    std::vector<ImportEdge> edgeList;
    NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
    in.close();
    INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");

    /***
     * Building an edge-expanded graph from node-based input an turn restrictions
     */

    INFO("Starting SCC graph traversal");
    TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping);
    std::vector<ImportEdge>().swap(edgeList);
    tarjan->Run();
    std::vector<_Restriction>().swap(inputRestrictions);
    std::vector<NodeID>().swap(bollardNodes);
    std::vector<NodeID>().swap(trafficLightNodes);
    INFO("finished component analysis");
    return 0;
}
<|endoftext|>


<commit_before>//
// Hello World client
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server, expects "World" back
//
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <getopt.h>
#include <pthread.h>

#include <string>
#include <map>
#include <algorithm>
#include <iostream>

#include "ProtocolBuffers/arangodb.pb.h"

using namespace std;

void* context = 0;

// default values
size_t loop = 10000;
size_t concurrency = 1;
size_t pipelined = 1;
char const* connection = "tcp://localhost:5555";
char const* path = "/_api/version";
bool verbose = false;
map<string, string> headers;
map<string, string> values;

void* ThreadStarter (void* data) {
  int res;
  size_t n;
  void* requester;

  requester = zmq_socket(context, ZMQ_REQ);
  res = zmq_connect(requester, connection);

  if (res != 0) {
    printf("ERROR zmq_connect: %d\n", errno);
    exit(EXIT_FAILURE);
  }

  if (verbose) {
    printf("connected\n");
  }

  for (n = 0; n < loop; n += pipelined) {
    zmq_msg_t request;
    zmq_msg_t reply;

    PB_ArangoMessage messages;
    PB_ArangoBatchMessage* batch;
    PB_ArangoBlobRequest* blob;
    PB_ArangoKeyValue* kv;

    for (size_t p = 0; p < pipelined; p++) {
      batch = messages.add_messages();

      batch->set_type(PB_BLOB_REQUEST);
      blob = batch->mutable_request();

      map<string, string>::iterator it;

      for (it = headers.begin(); it != headers.end(); ++it) {
        kv = blob->add_headers();
        kv->set_key((*it).first);
        kv->set_value((*it).second);
      }

      for (it = values.begin(); it != values.end(); ++it) {
        kv = blob->add_values();
        kv->set_key((*it).first);
        kv->set_value((*it).second);
      }

      blob->set_requesttype(PB_REQUEST_TYPE_GET);
      blob->set_url(path);
      blob->set_contenttype(PB_NO_CONTENT);
      blob->set_contentlength(0);
      blob->set_content("");
    }

    string data;
    messages.SerializeToString(&data);

    // send
    zmq_msg_init_size(&request, data.size());
    memcpy(zmq_msg_data(&request), data.c_str(), data.size());

    res = zmq_send(requester, &request, 0);

    if (res != 0) {
      printf("ERROR zmq_send: %d %d %s\n", (int) res, (int) errno, strerror(errno));
    }

    zmq_msg_close(&request);

    // receive
    zmq_msg_init(&reply);

    res = zmq_recv(requester, &reply, 0);

    if (res != 0) {
      printf("ERROR zmq_recv: %d %d %s\n", (int) res, (int) errno, strerror(errno));
    }

    zmq_msg_close(&reply);
  }

  zmq_close(requester);

  return 0;
}

/* Return 1 if the difference is negative, otherwise 0.  */
int timeval_subtract(struct timeval* result, struct timeval* t2, struct timeval* t1) {
  long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
  result->tv_sec = diff / 1000000;
  result->tv_usec = diff % 1000000;

  return (diff<0);
}

void addHeader (char* arg) {
  string header(arg);
  size_t found = header.find('=', 0);

  if (found == string::npos) {
    fprintf(stderr, "invalid header %s\n", arg);
    exit(EXIT_FAILURE);
  }

  string key(header.substr(0, found));
  string value(header.substr(found + 1, header.length() - found - 1));

  std::transform(key.begin(), key.end(), key.begin(), ::tolower);
  headers[key] = value;
}

void addValue (char* arg) {
  string data(arg);
  size_t found = data.find('=', 0);

  if (found == string::npos) {
    fprintf(stderr, "invalid value %s\n", arg);
    exit(EXIT_FAILURE);
  }

  string key(data.substr(0, found));
  string value(data.substr(found + 1, data.length() - found - 1));

  values[key] = value;
}

void printUsage (char* prg) {
  fprintf(stderr, "Usage: %s [-C connection] [-u path] [-h \"key=value\"] [-v \"key=value\"] [-P pipeline] [-c concurrency] [-n count] [-d]\n", prg);
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "-C connection       connection string, e.g. tcp://localhost:5555\n");
  fprintf(stderr, "-u path             endpoint to call, e.g. /_api/version\n");
  fprintf(stderr, "-h \"key=value\"      add arbitrary header\n");
  fprintf(stderr, "-v \"key=value\"      add arbitrary body value\n");
  fprintf(stderr, "-P pipeline         send <pipeline> values in each batch (default: 1)\n");
  fprintf(stderr, "-c concurrency      number of concurrent client threads (default: 1)\n");
  fprintf(stderr, "-n count            number of requests to perform per client thread\n");
}

int main (int argc, char* argv[]) {
  struct timeval start, end, result;
  float rps, runtime;
  size_t i;
  int opt;
  pthread_t* threads;

  while ((opt = getopt(argc, argv, "C:u:h:v:P:c:n:d")) != -1) {
    switch (opt) {
      case 'C':
        connection = optarg;
        break;
      case 'u':
        path = optarg;
        break;
      case 'h':
        addHeader(optarg);
        break;
      case 'v':
        addValue(optarg);
        break;
      case 'P':
        pipelined = atoi(optarg);
        if (pipelined < 1) {
          fprintf(stderr, "pipeline argument must be at least 1\n");
          exit(EXIT_FAILURE);
        }
        break;
      case 'c':
        concurrency = atoi(optarg);
        if (concurrency < 1) {
          fprintf(stderr, "concurrency must be at least 1\n");
          exit(EXIT_FAILURE);
        }
        break;
      case 'n':
        loop = atoi(optarg);
        break;
      case 'd':
        verbose = true;
        break;
      default:
        printUsage(argv[0]);
        exit(EXIT_FAILURE);
    }
  }

  printf("Looping %d times per thread, total %d, pipelined %d\n", (int) loop, (int) (loop * concurrency), (int) pipelined);
  printf("Concurrency %d\n", (int) concurrency);
  printf("Connection %s\n", connection);

  context = zmq_init(16);

  if (verbose) {
    printf("Connecting to server…\n");
  }

  threads = (pthread_t*) malloc(sizeof(pthread_t) * concurrency);

  for (i = 0;  i < concurrency;  ++i) {
    pthread_create(&threads[i], 0, &ThreadStarter, 0);
  }

  gettimeofday(&start, 0);

  for (i = 0;  i < concurrency;  ++i) {
    pthread_join(threads[i], 0);
  }

  gettimeofday(&end, 0);
  timeval_subtract(&result, &end, &start);
  runtime = (float) result.tv_sec + (float) ((float) result.tv_usec / 1000000.0);

  rps = (float) loop * (float) concurrency / runtime;
  printf("runtime %f sec, req/sec %f, req/sec/thread %f\n", runtime, rps, rps / (float) concurrency);

  zmq_term(context);
  free(threads);

  threads = 0;
  context = 0;

  return 0;
}
<commit_msg>sync all clients<commit_after>//
// Hello World client
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server, expects "World" back
//
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <getopt.h>
#include <pthread.h>

#include <string>
#include <map>
#include <algorithm>
#include <iostream>

#include "ProtocolBuffers/arangodb.pb.h"

using namespace std;

void* context = 0;
size_t errors = 0;
pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
bool canStart = false;

// default values
size_t loop = 10000;
size_t concurrency = 1;
size_t pipelined = 1;
char const* connection = "tcp://localhost:5555";
char const* path = "/_api/version";
bool verbose = false;
map<string, string> headers;
map<string, string> values;

void* ThreadStarter (void* data) {
  int res, rc;
  size_t n;
  void* requester;

  requester = zmq_socket(context, ZMQ_REQ);
  res = zmq_connect(requester, connection);

  if (res != 0) {
    printf("ERROR zmq_connect: %d\n", errno);
    exit(EXIT_FAILURE);
  }

  if (verbose) {
    printf("connected\n");
  }

  rc = pthread_mutex_lock(&mutex);

  while (!canStart) {
    rc = pthread_cond_wait(&condition, &mutex);
  }

  rc = pthread_mutex_unlock(&mutex);

  for (n = 0; n < loop; n += pipelined) {
    zmq_msg_t request;
    zmq_msg_t reply;

    PB_ArangoMessage messages;
    PB_ArangoBatchMessage* batch;
    PB_ArangoBlobRequest* blob;
    PB_ArangoKeyValue* kv;

    for (size_t p = 0; p < pipelined; p++) {
      batch = messages.add_messages();

      batch->set_type(PB_BLOB_REQUEST);
      blob = batch->mutable_request();

      map<string, string>::iterator it;

      for (it = headers.begin(); it != headers.end(); ++it) {
        kv = blob->add_headers();
        kv->set_key((*it).first);
        kv->set_value((*it).second);
      }

      for (it = values.begin(); it != values.end(); ++it) {
        kv = blob->add_values();
        kv->set_key((*it).first);
        kv->set_value((*it).second);
      }

      blob->set_requesttype(PB_REQUEST_TYPE_GET);
      blob->set_url(path);
      blob->set_contenttype(PB_NO_CONTENT);
      blob->set_contentlength(0);
      blob->set_content("");
    }

    string data;
    messages.SerializeToString(&data);

    // send
    zmq_msg_init_size(&request, data.size());
    memcpy(zmq_msg_data(&request), data.c_str(), data.size());

    res = zmq_send(requester, &request, 0);

    if (res != 0) {
      printf("ERROR zmq_send: %d %d %s\n", (int) res, (int) errno, strerror(errno));
      ++errors;
    }

    zmq_msg_close(&request);

    // receive
    zmq_msg_init(&reply);

    res = zmq_recv(requester, &reply, 0);

    if (res != 0) {
      printf("ERROR zmq_recv: %d %d %s\n", (int) res, (int) errno, strerror(errno));
      ++errors;
    }

    zmq_msg_close(&reply);
  }

  zmq_close(requester);

  return 0;
}

/* Return 1 if the difference is negative, otherwise 0.  */
int timeval_subtract(struct timeval* result, struct timeval* t2, struct timeval* t1) {
  long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
  result->tv_sec = diff / 1000000;
  result->tv_usec = diff % 1000000;

  return (diff<0);
}

void addHeader (char* arg) {
  string header(arg);
  size_t found = header.find('=', 0);

  if (found == string::npos) {
    fprintf(stderr, "invalid header %s\n", arg);
    exit(EXIT_FAILURE);
  }

  string key(header.substr(0, found));
  string value(header.substr(found + 1, header.length() - found - 1));

  std::transform(key.begin(), key.end(), key.begin(), ::tolower);
  headers[key] = value;
}

void addValue (char* arg) {
  string data(arg);
  size_t found = data.find('=', 0);

  if (found == string::npos) {
    fprintf(stderr, "invalid value %s\n", arg);
    exit(EXIT_FAILURE);
  }

  string key(data.substr(0, found));
  string value(data.substr(found + 1, data.length() - found - 1));

  values[key] = value;
}

void printUsage (char* prg) {
  fprintf(stderr, "Usage: %s [-C connection] [-u path] [-h \"key=value\"] [-v \"key=value\"] [-P pipeline] [-c concurrency] [-n count] [-d]\n", prg);
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "-C connection       connection string, e.g. tcp://localhost:5555\n");
  fprintf(stderr, "-u path             endpoint to call, e.g. /_api/version\n");
  fprintf(stderr, "-h \"key=value\"      add arbitrary header\n");
  fprintf(stderr, "-v \"key=value\"      add arbitrary body value\n");
  fprintf(stderr, "-P pipeline         send <pipeline> values in each batch (default: 1)\n");
  fprintf(stderr, "-c concurrency      number of concurrent client threads (default: 1)\n");
  fprintf(stderr, "-n count            number of requests to perform per client thread\n");
}

int main (int argc, char* argv[]) {
  struct timeval start, end, result;
  float rps, runtime;
  size_t i;
  int opt, rc;
  pthread_t* threads;

  while ((opt = getopt(argc, argv, "C:u:h:v:P:c:n:d")) != -1) {
    switch (opt) {
      case 'C':
        connection = optarg;
        break;
      case 'u':
        path = optarg;
        break;
      case 'h':
        addHeader(optarg);
        break;
      case 'v':
        addValue(optarg);
        break;
      case 'P':
        pipelined = atoi(optarg);
        if (pipelined < 1) {
          fprintf(stderr, "pipeline argument must be at least 1\n");
          exit(EXIT_FAILURE);
        }
        break;
      case 'c':
        concurrency = atoi(optarg);
        if (concurrency < 1) {
          fprintf(stderr, "concurrency must be at least 1\n");
          exit(EXIT_FAILURE);
        }
        break;
      case 'n':
        loop = atoi(optarg);
        break;
      case 'd':
        verbose = true;
        break;
      default:
        printUsage(argv[0]);
        exit(EXIT_FAILURE);
    }
  }

  printf("Looping %d times per thread, total %d, pipelined %d\n", (int) loop, (int) (loop * concurrency), (int) pipelined);
  printf("Concurrency %d\n", (int) concurrency);
  printf("Connection %s\n", connection);

  context = zmq_init(16);

  if (verbose) {
    printf("Connecting to server…\n");
  }

  threads = (pthread_t*) malloc(sizeof(pthread_t) * concurrency);

  for (i = 0;  i < concurrency;  ++i) {
    pthread_create(&threads[i], 0, &ThreadStarter, 0);
  }

  gettimeofday(&start, 0);
  rc = pthread_mutex_lock(&mutex);
  canStart = true;
  rc = pthread_cond_broadcast(&condition);
  rc = pthread_mutex_unlock(&mutex);

  for (i = 0;  i < concurrency;  ++i) {
    pthread_join(threads[i], 0);
  }

  gettimeofday(&end, 0);
  timeval_subtract(&result, &end, &start);
  runtime = (float) result.tv_sec + (float) ((float) result.tv_usec / 1000000.0);

  rps = (float) loop * (float) concurrency / runtime;
  printf("runtime %f sec, req/sec %f, req/sec/thread %f\n", runtime, rps, rps / (float) concurrency);
  printf("errors %ld\n", (long int) errors);

  zmq_term(context);
  free(threads);

  pthread_cond_destroy(&condition);
  pthread_mutex_destroy(&mutex);

  return 0;
}
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(h), h is the depth of the recursion

class Solution {
public:
    string decodeString(string s) {
        string curr;
        stack<int> nums;
        stack<string> strs;
        int n = 0;
        for (int i = 0; i < s.length(); ++i) {
            if (isdigit(s[i])) {
                n = n * 10 + s[i] - '0';
            } else if (s[i] == '[') {
                nums.emplace(n);
                n = 0;
                strs.emplace(curr);
                curr.clear();
            } else if (s[i] == ']') {
                for (; nums.top() > 0; --nums.top()) {
                    strs.top() += curr;
                }
                nums.pop();
                curr = strs.top();
                strs.pop();
            } else {
                curr += s[i];
            }
        }
        return strs.empty() ? curr : strs.top();
    }
};
<commit_msg>Update decode-string.cpp<commit_after>// Time:  O(n)
// Space: O(h), h is the depth of the recursion

class Solution {
public:
    string decodeString(string s) {
        string curr;
        stack<int> nums;
        stack<string> strs;
        int n = 0;
        for (const auto& c: s) {
            if (isdigit(c)) {
                n = n * 10 + c - '0';
            } else if (c == '[') {
                nums.emplace(n);
                n = 0;
                strs.emplace(curr);
                curr.clear();
            } else if (c == ']') {
                for (; nums.top() > 0; --nums.top()) {
                    strs.top() += curr;
                }
                nums.pop();
                curr = strs.top();
                strs.pop();
            } else {
                curr += c;
            }
        }
        return strs.empty() ? curr : strs.top();
    }
};
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    /**
     * @param A: Array of integers.
     * return: The single number.
     */
    int singleNumber(vector<int> &A) {
        int single = 0;
        for (auto& i : A) {
            single ^= i;
        }

        return single;
    }
};

<commit_msg>Update single-number.cpp<commit_after>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    /**
     * @param A: Array of integers.
     * return: The single number.
     */
    int singleNumber(vector<int> &A) {
        int single = 0;
        for (const auto& i : A) {
            single ^= i;
        }

        return single;
    }
};
<|endoftext|>