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

#include <QDebug>
#include <QDir>
#include <QStringList>
#include <QFile>
#include <QTextStream>
#include <QDomDocument>
#include <QDomNode>
#include <QDomNodeList>

int main(int argc, char *argv[])
{
    Q_UNUSED(argc);
    Q_UNUSED(argv);
    QString dirPath = QDir::homePath() + QDir::separator();
    QDir myDir(dirPath);
    QStringList fileList = myDir.entryList(QStringList() << "benchmark-*.xml");
    QString pageOutput;
    pageOutput = ""
    ""
    "<title>Benchmark result comparison</title>"
    ""
    ""
    "
Report generated by Benchmark Comparison Tool (part of QSparql test library)
";
    QHash<QString, QStringList> results;
    QHash<QString, QString> tracker_ver;
    QHash<QString, QString> qsparql_ver;
    QStringList testNames;

    //lets iterate through files, read them and parse
    for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
    {
        QString filename(dirPath+fileList.at(dirIterator));
        QDomDocument doc("xmlResult");
        QFile file(filename);
        if (!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "Couldn't open file "<< filename;
            pageOutput.append("Error: Couldn't open file "+filename);
        }
        else
        if (!doc.setContent(&file)) {
            file.close();
            qDebug() << "Couldn't set file content for  QDomDocument "<< filename;
            pageOutput.append("Couldn't set file content for  QDomDocument  "+filename);
        }
        else
        {
            file.close();

            QDomNode asset = doc.elementsByTagName("benchmark").at(0).firstChild();
            QDomNode assetIterator = asset.firstChild();
            QString tracker, qsparql, created;
            for(QDomNode assetIterator = asset.firstChild(); !assetIterator.isNull();
                                                assetIterator = assetIterator.nextSibling())
            {
                QString tagName = assetIterator.toElement().tagName();
                if(tagName == "tracker")
                    tracker = assetIterator.toElement().text();
                else if(tagName == "qsparql")
                    qsparql = assetIterator.toElement().text();
                else if(tagName == "created")
                    created = assetIterator.toElement().text();
            }

            //QString description = assetIterator.toElement().text();
            tracker_ver[fileList.at(dirIterator)]=tracker;
            qsparql_ver[fileList.at(dirIterator)]=qsparql;
            QDomNodeList testList = doc.elementsByTagName("benchmark").at(0).lastChild().
                                    toElement().elementsByTagName("test");
            for(int i=0; i< testList.count(); i++)
            {
                QString name = testList.at(i).toElement().attribute("name");
                if(!testNames.contains(name))
                    testNames << name;
                QDomNode median = testList.at(i).toElement().firstChild();
                QString medianValue = median.toElement().attribute("value");
                QDomNode mean = median.nextSibling();
                QString meanValue = mean.toElement().attribute("value");
                QDomNode total = mean.nextSibling();
                QString totalValue = total.toElement().attribute("value");
                QStringList runResults;
                runResults << medianValue << meanValue << totalValue;
                results[fileList.at(dirIterator)+name] = runResults;
            }
        }
    }

    pageOutput.append("

Test name	");
    for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
    {
        QStringList nameparts = fileList.at(dirIterator).split(".");
        pageOutput.append("" + nameparts[0] + "
" +nameparts[1] + "
"+
                          qsparql_ver[fileList.at(dirIterator)]+"
"+
                          ""+tracker_ver[fileList.at(dirIterator)]+"	");
    }
    pageOutput.append("
\n");
    QStringList previousResult;
    for(int testIterator=0; testIterator < testNames.count(); testIterator++)
    {
        previousResult.clear();
        pageOutput.append(QString("
"+testNames[testIterator].remove(".xml")+
                          "
median
mean
total	");
        for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
        {
            pageOutput.append("");
            for(int partResultIterator=0; partResultIterator < results[fileList.at(dirIterator)+
                                            testNames[testIterator]].count(); partResultIterator++)
            {
                int currentValue=results[fileList.at(dirIterator)+testNames[testIterator]].
                                                            at(partResultIterator).toInt();
                pageOutput.append(QString("%1").arg(currentValue));
                if(previousResult.count() == results[fileList.at(dirIterator)+
                   testNames[testIterator]].count() && previousResult.count()-1 == partResultIterator)
                {
                    int previousValue=previousResult[partResultIterator].toInt();
                    int diff = (previousValue?(((previousValue-currentValue)*100)/previousValue):100);
                    pageOutput.append(QString("  %1%").arg(diff*-1).
                                                                        arg(diff<0?"1":"2"));
                }
                pageOutput.append("
");
            }
            pageOutput.append("	\n");
            previousResult = results[fileList.at(dirIterator)+testNames[testIterator]];
        }
        pageOutput.append("
\n\n");
    }
    pageOutput.append("

");
    pageOutput.append("");
    QFile data(dirPath+"index.html");
    if (data.open(QFile::WriteOnly | QFile::Truncate)) {
        QTextStream out(&data);
        out << pageOutput;
        qDebug() << "Report saved in " << dirPath;
    }
    else
        qDebug() << "Couldn't save report in " << dirPath << "Check writing permissions!";
    return 0;
}<commit_msg>Added subpage generation with between-tests comaprison<commit_after>/****************************************************************************
**
** Copyright (C) 2010-2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (ivan.frade@nokia.com)
**
** This file is part of the test suite of the QtSparql module (not yet part of the Qt Toolkit).
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at ivan.frade@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QDebug>
#include <QDir>
#include <QStringList>
#include <QFile>
#include <QTextStream>
#include <QDomDocument>
#include <QDomNode>
#include <QDomNodeList>

QString makeTable(QHash<QString, QStringList> &results, QString fileName,
                  QString testName1, QString testName2)
{
    int test1Total = results[fileName+testName1].at(2).toInt();
    int test2Total = results[fileName+testName2].at(2).toInt();
    int fasterTime, slowerTime;
    if(test1Total<test2Total)
    {
        fasterTime=test1Total;
        slowerTime=test2Total;
    }
    else
    {
        fasterTime=test2Total;
        slowerTime=test1Total;
    }
    bool isFirstFaster=(test1Total < test2Total ? true:false);
    QString table("

	"
        "%3	%4

median
mean
total	"
        "%5	%6	%7 is faster by %8%	"
        "

");
    return table.arg(QString(isFirstFaster?"g":"w")).arg(QString((isFirstFaster?"w":"g"))).
    arg(testName1).arg(testName2).arg(results[fileName+testName1].join("
")).
    arg(results[fileName+testName2].join("
")).arg((isFirstFaster?testName1:testName2)).
    arg(((slowerTime-fasterTime)*100)/slowerTime);
}

QString makeTableCombined(QHash<QString, QStringList> &results, QString fileName,
                  QStringList testNames1, QStringList testNames2)
{
    int test1Total = 0;
    for(int i=0; i<testNames1.count(); i++)
        test1Total+= results[fileName+testNames1[i]].at(2).toInt();
    int test2Total = 0;
    for(int i=0; i<testNames2.count(); i++)
        test2Total+= results[fileName+testNames2[i]].at(2).toInt();
    int fasterTime, slowerTime;
    if(test1Total<test2Total)
    {
        fasterTime=test1Total;
        slowerTime=test2Total;
    }
    else
    {
        fasterTime=test2Total;
        slowerTime=test1Total;
    }
    bool isFirstFaster=(test1Total < test2Total ? true:false);
    QString table("

	"
    "%3	%4

total	"
    "%5	%6	%7 is faster by %8%"
    "

");
    return table.arg(QString(isFirstFaster?"g":"w")).arg((isFirstFaster?"w":"g")).arg(testNames1.join(" + ")).
    arg(testNames2.join(" + ")).arg(test1Total).arg(test2Total).arg((isFirstFaster?testNames1:testNames2)
    .join(" + ")).arg(((slowerTime-fasterTime)*100)/slowerTime);
}
int main(int argc, char *argv[])
{
    Q_UNUSED(argc);
    Q_UNUSED(argv);
    QString dirPath = QDir::homePath() + QDir::separator();
    QDir myDir(dirPath);
    QStringList fileList = myDir.entryList(QStringList() << "benchmark-*.xml");
    QString pageOutput;
    pageOutput = ""
    ""
    "<title>Benchmark result comparison</title>"
    ""
    ""
    "
Report generated by Benchmark Comparison Tool (part of QSparql test library)
";
    QHash<QString, QStringList> results;
    QHash<QString, QString> tracker_ver;
    QHash<QString, QString> qsparql_ver;
    QStringList testNames;
    QString pageOutput2(pageOutput);

    //lets iterate through files, read them and parse
    for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
    {
        QString filename(dirPath+fileList.at(dirIterator));
        QDomDocument doc("xmlResult");
        QFile file(filename);
        if (!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "Couldn't open file "<< filename;
            pageOutput.append("Error: Couldn't open file "+filename);
        }
        else
        if (!doc.setContent(&file)) {
            file.close();
            qDebug() << "Couldn't set file content for  QDomDocument "<< filename;
            pageOutput.append("Couldn't set file content for  QDomDocument  "+filename);
        }
        else
        {
            file.close();

            QDomNode asset = doc.elementsByTagName("benchmark").at(0).firstChild();
            QDomNode assetIterator = asset.firstChild();
            QString tracker, qsparql, created;
            for(QDomNode assetIterator = asset.firstChild(); !assetIterator.isNull();
                                                assetIterator = assetIterator.nextSibling())
            {
                QString tagName = assetIterator.toElement().tagName();
                if(tagName == "tracker")
                    tracker = assetIterator.toElement().text();
                else if(tagName == "qsparql")
                    qsparql = assetIterator.toElement().text();
                else if(tagName == "created")
                    created = assetIterator.toElement().text();
            }

            //QString description = assetIterator.toElement().text();
            tracker_ver[fileList.at(dirIterator)]=tracker;
            qsparql_ver[fileList.at(dirIterator)]=qsparql;
            QDomNodeList testList = doc.elementsByTagName("benchmark").at(0).lastChild().
                                    toElement().elementsByTagName("test");
            for(int i=0; i< testList.count(); i++)
            {
                QString name = testList.at(i).toElement().attribute("name");
                if(!testNames.contains(name))
                    testNames << name;
                QDomNode median = testList.at(i).toElement().firstChild();
                QString medianValue = median.toElement().attribute("value");
                QDomNode mean = median.nextSibling();
                QString meanValue = mean.toElement().attribute("value");
                QDomNode total = mean.nextSibling();
                QString totalValue = total.toElement().attribute("value");
                QStringList runResults;
                runResults << medianValue << meanValue << totalValue;
                results[fileList.at(dirIterator)+name] = runResults;
            }
        }
    }

    //overall comparison html page
    pageOutput.append("

Test name	");
    for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
    {
        QStringList nameparts = fileList.at(dirIterator).split(".");
        pageOutput.append("" + nameparts[0] + "
" +nameparts[1] + "
"+
                          qsparql_ver[fileList.at(dirIterator)]+"
"+
                          ""+tracker_ver[fileList.at(dirIterator)]+"" +
                          "
tests comaprison	");
    }
    pageOutput.append("
\n");
    QStringList previousResult;
    for(int testIterator=0; testIterator < testNames.count(); testIterator++)
    {
        previousResult.clear();
        pageOutput.append(QString("
"+testNames[testIterator].remove(".xml")+
                          "
median
mean
total	");
        for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
        {
            pageOutput.append("");
            for(int partResultIterator=0; partResultIterator < results[fileList.at(dirIterator)+
                                            testNames[testIterator]].count(); partResultIterator++)
            {
                int currentValue=results[fileList.at(dirIterator)+testNames[testIterator]].
                                                            at(partResultIterator).toInt();
                pageOutput.append(QString("%1").arg(currentValue));
                if(previousResult.count() == results[fileList.at(dirIterator)+
                   testNames[testIterator]].count() && previousResult.count()-1 == partResultIterator)
                {
                    int previousValue=previousResult[partResultIterator].toInt();
                    int diff = (previousValue?(((previousValue-currentValue)*100)/previousValue):100);
                    pageOutput.append(QString("  %1%").arg(diff*-1).
                                                                        arg(diff<0?"1":"2"));
                }
                pageOutput.append("
");
            }
            pageOutput.append("	\n");
            previousResult = results[fileList.at(dirIterator)+testNames[testIterator]];
        }
        pageOutput.append("
\n\n");
    }
    pageOutput.append("

");
    pageOutput.append("");

    //between-tests-comparison html page
    pageOutput2.append("
In-between tests comaprison
Back to the mainpage

");
    for(int dirIterator=0; dirIterator < fileList.count(); dirIterator++)
    {
        QStringList nameparts = fileList.at(dirIterator).split(".");
        pageOutput2.append("
" +
        "

"+ nameparts[0]+ "." + nameparts[1] +"
" + ""+
        qsparql_ver[fileList.at(dirIterator)]+"
"+
        ""+tracker_ver[fileList.at(dirIterator)]+"

" +
        makeTable(results, fileList.at(dirIterator), "read-music-Async-fin", "read-music-Sync-fin")+
        makeTable(results, fileList.at(dirIterator), "read-music-Async-read", "read-music-Sync-read")+
        makeTable(results, fileList.at(dirIterator), "read-music-Async-ForwardOnly-fin", "read-music-Async-fin")+
        makeTable(results, fileList.at(dirIterator), "read-music-Async-ForwardOnly-read", "read-music-Async-read")+
        makeTableCombined(results, fileList.at(dirIterator), QStringList() << "read-music-Async-fin"
                            << "read-music-Async-read", QStringList() << "read-music-Sync-fin" << "read-music-Sync-read")+
        makeTableCombined(results, fileList.at(dirIterator), QStringList() << "read-music-Async-fin"
                            << "read-music-Async-read", QStringList() << "read-music-Async-ForwardOnly-fin"
                            << "read-music-Async-ForwardOnly-read"));
    }
    pageOutput2.append("");

    QFile data(dirPath+"index.html");
    if (data.open(QFile::WriteOnly | QFile::Truncate)) {
        QTextStream out(&data);
        out << pageOutput;
        qDebug() << "Report saved in " << dirPath;
        data.close();
    }
    else
        qDebug() << "Couldn't save report in " << dirPath << "Check writing permissions!";
    data.setFileName(dirPath+"tests-comparison.html");
    if (data.open(QFile::WriteOnly | QFile::Truncate)) {
        QTextStream out(&data);
        out << pageOutput2;
        qDebug() << "Report saved in " << dirPath;
    }
    else
        qDebug() << "Couldn't save report in " << dirPath << "Check writing permissions!";
    return 0;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WExtendPages.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:10:15 $
 *
 *  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 DBAUI_WIZ_EXTENDPAGES_HXX
#include "WExtendPages.hxx"
#endif
#ifndef DBAUI_RTFREADER_HXX
#include "RtfReader.hxx"
#endif
#ifndef DBAUI_HTMLREADER_HXX
#include "HtmlReader.hxx"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif

using namespace dbaui;
//========================================================================
SvParser* OWizHTMLExtend::createReader(sal_Int32 _nRows)
{
    return new OHTMLReader(*m_pParserStream,
                            _nRows,
                            m_pParent->GetColumnPositions(),
                            m_pParent->GetFormatter(),
                            m_pParent->GetFactory(),
                            m_pParent->getDestVector(),
                            m_pParent->getTypeInfo());
}
//========================================================================
SvParser* OWizRTFExtend::createReader(sal_Int32 _nRows)
{
    return new ORTFReader(*m_pParserStream,
                            _nRows,
                            m_pParent->GetColumnPositions(),
                            m_pParent->GetFormatter(),
                            m_pParent->GetFactory(),
                            m_pParent->getDestVector(),
                            m_pParent->getTypeInfo());
}
//========================================================================
OWizNormalExtend::OWizNormalExtend(Window* pParent) : OWizTypeSelect( pParent)
{
    EnableAuto(sal_False);
    Size aflSize( m_flColumns.GetSizePixel() );
    Point aPos(m_flColumns.GetPosPixel());

    m_flColumns.SetPosSizePixel(aPos, aflSize );

    sal_Int32 nHeight = m_lbColumnNames.GetSizePixel().Height() +6;
    aPos = m_aTypeControl.GetPosPixel();
    Size aNewSize(m_aTypeControl.GetSizePixel().Width(),nHeight - aPos.Y()-6);

    aflSize = m_aTypeControl.GetSizePixel();
    m_aTypeControl.SetPosSizePixel(aPos,aNewSize);
}
// -----------------------------------------------------------------------------
SvParser* OWizNormalExtend::createReader(sal_Int32 _nRows)
{
    return NULL;
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS dba203c (1.4.110); FILE MERGED 2006/04/13 13:55:20 oj 1.4.110.1: #i62797# format regconition corrected<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WExtendPages.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2006-05-04 08:45:22 $
 *
 *  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 DBAUI_WIZ_EXTENDPAGES_HXX
#include "WExtendPages.hxx"
#endif
#ifndef DBAUI_RTFREADER_HXX
#include "RtfReader.hxx"
#endif
#ifndef DBAUI_HTMLREADER_HXX
#include "HtmlReader.hxx"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif

using namespace dbaui;
//========================================================================
SvParser* OWizHTMLExtend::createReader(sal_Int32 _nRows)
{
    return new OHTMLReader(*m_pParserStream,
                            _nRows,
                            m_pParent->GetColumnPositions(),
                            m_pParent->GetFormatter(),
                            m_pParent->GetFactory(),
                            m_pParent->getDestVector(),
                            m_pParent->getTypeInfo(),
                            m_pParent->isAutoincrementEnabled());
}
//========================================================================
SvParser* OWizRTFExtend::createReader(sal_Int32 _nRows)
{
    return new ORTFReader(*m_pParserStream,
                            _nRows,
                            m_pParent->GetColumnPositions(),
                            m_pParent->GetFormatter(),
                            m_pParent->GetFactory(),
                            m_pParent->getDestVector(),
                            m_pParent->getTypeInfo(),
                            m_pParent->isAutoincrementEnabled());
}
//========================================================================
OWizNormalExtend::OWizNormalExtend(Window* pParent) : OWizTypeSelect( pParent)
{
    EnableAuto(sal_False);
    Size aflSize( m_flColumns.GetSizePixel() );
    Point aPos(m_flColumns.GetPosPixel());

    m_flColumns.SetPosSizePixel(aPos, aflSize );

    sal_Int32 nHeight = m_lbColumnNames.GetSizePixel().Height() +6;
    aPos = m_aTypeControl.GetPosPixel();
    Size aNewSize(m_aTypeControl.GetSizePixel().Width(),nHeight - aPos.Y()-6);

    aflSize = m_aTypeControl.GetSizePixel();
    m_aTypeControl.SetPosSizePixel(aPos,aNewSize);
}
// -----------------------------------------------------------------------------
SvParser* OWizNormalExtend::createReader(sal_Int32 _nRows)
{
    return NULL;
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2012-2014 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_OPTPARSE_OPTION_HPP
#define GEARS_OPTPARSE_OPTION_HPP

#include "value.hpp"

namespace gears {
namespace optparse {
/**
 * @ingroup optparse
 * @brief Represents a command line option.
 * @details A class that represents a command line option. A command line
 * option is a command line argument used to specify information to the
 * program.
 *
 */
struct option {
private:
    using value_type = std::unique_ptr<value_base>;
    value_type ptr = nullptr;
    friend struct option_parser;
public:
    std::string name;   ///< The long name of the option, e.g. "help"
    std::string help;   ///< The description used for the help output
    char alias = '\0';  ///< The short name of the option, e.g. 'h'

    /**
     * @brief Constructs an option from a long name, a description, and a value
     */
    option(std::string name, std::string help = "", value_type value = nullptr):
        ptr(std::move(value)), name(std::move(name)), help(std::move(help)) {}
    /**
     * @brief Constructs an option from a long name, short name, a description, and a value.
     */
    option(std::string name, char alias, std::string help = "", value_type value = nullptr):
        ptr(std::move(value)), name(std::move(name)), help(std::move(help)), alias(alias) {}

    /**
     * @brief Constructs an option from a short name, description and value.
     */
    option(char alias, std::string help = "", value_type value = nullptr):
        ptr(std::move(value)), help(std::move(help)), alias(alias) {}

    /**
     * @brief Copy constructor
     */
    option(const option& other):
        ptr(other.ptr == nullptr ? nullptr : other.ptr->clone()),
        name(other.name), help(other.help), alias(other.alias) {}

    /**
     * @brief Copy assignment
     */
    option& operator=(const option& other) {
        ptr = other.ptr == nullptr ? nullptr : other.ptr->clone();
        name = other.name;
        help = other.help;
        alias = other.alias;
        return *this;
    }

    /**
     * @brief Move constructor
     */
    option(option&&) = default;

    /**
     * @brief Move assignment
     */
    option& operator=(option&&) = default;

    /**
     * @brief Destructor
     */
    ~option() = default;

    /**
     * @brief Checks if the option accepts a value.
     */
    bool takes_value() const noexcept {
        return ptr != nullptr && ptr->nargs > 0;
    }

    /**
     * @brief Returns the number of arguments expected by the value.
     * @return Returns the number of arguments expected by the value.
     * If no value is expected, i.e. #takes_value is false, then 0 is
     * returned.
     */
    size_t nargs() const noexcept {
        return takes_value() ? ptr->nargs : 0;
    }

    //@{
    /**
     * @brief Checks if the option is represented by a long or short option.
     * @details Checks if the option is represented by a long or short option.
     * This function is typically used to avoid code repetition when handling
     * predicates dealing with checking for a long name or short name. This
     * is a member function rather than an `operator==` or `operator!=` to
     * disallow obfuscation and code duplication (e.g. `"help" == op` vs `op == "help"`).
     *
     * Example usage:
     *
     * @code
     * optparse::option x = { "help", 'h', "show message" };
     * x.is("help");    // true
     * x.is('h');       // true
     * x.is("stuff");   // false
     * @endcode
     *
     * @param arg Long or short option to check for.
     * @return `true` if the option can be represented by arg.
     */
    bool is(char arg) const noexcept {
        return alias == arg;
    }

    bool is(const std::string& arg) const noexcept {
        return name == arg;
    }
    //@}

    /**
     * @brief Retrieves the internal value of the option.
     * @details Retrieves the internal value of the option.
     * If the option has no value then an exception is thrown.
     *
     * @throws std::runtime_error Thrown if the option has not been parsed.
     * @throws std::invalid_argument Thrown for invalid casting or if the option has no value.
     * @return The internal value.
     */
    template<typename T>
    const T& get() const {
        if(ptr == nullptr) {
            throw std::invalid_argument("option does not take value");
        }
        auto val = dynamic_cast<typed_value<T>*>(ptr.get());

        if(val == nullptr) {
            throw std::invalid_argument("invalid cast for option");
        }
        return val->get();
    }

    /**
     * @brief Retrieves the internal value of the option or a reasonable default.
     * @details Retrieves the internal value of the option or a reasonable default.
     * If the option has no value then the default is returned. If the type is not
     * a valid cast then the default is returned.
     *
     * @return The internal value or a reasonable default.
     */
    template<typename T>
    const T& get_or(const typename std::remove_reference<T>::type& def) const noexcept {
        if(ptr == nullptr) {
            return def;
        }

        auto val = dynamic_cast<typed_value<T>*>(ptr.get());
        return val == nullptr ? def : val->get_or(def);
    }

    /**
     * @brief Checks if the option has gone through parsing.
     */
    bool is_active() const noexcept {
        return ptr != nullptr && ptr->is_active();
    }

    /**
     * @brief Retrieves the internal option's metavar member.
     * @details Retrieves the internal value's metavar member. If
     * #takes_value returns false, then an empty string is returned.
     * @return The internal value's metavar member.
     */
    std::string metavar() const noexcept {
        return takes_value() ? ptr->metavar : "";
    }
};
} // optparse
} // gears

#endif // GEARS_OPTPARSE_OPTION_HPP
<commit_msg>Make options be boolean switches by default.<commit_after>// The MIT License (MIT)

// Copyright (c) 2012-2014 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_OPTPARSE_OPTION_HPP
#define GEARS_OPTPARSE_OPTION_HPP

#include "value.hpp"

namespace gears {
namespace optparse {
/**
 * @ingroup optparse
 * @brief Represents a command line option.
 * @details A class that represents a command line option. A command line
 * option is a command line argument used to specify information to the
 * program.
 *
 */
struct option {
private:
    using value_type = std::unique_ptr<value_base>;
    value_type ptr;
    friend struct option_parser;
public:
    std::string name;   ///< The long name of the option, e.g. "help"
    std::string help;   ///< The description used for the help output
    char alias = '\0';  ///< The short name of the option, e.g. 'h'

    /**
     * @brief Constructs an option from a long name, a description, and a value.
     */
    option(std::string name, std::string help = "", value_type value = constant(true)):
        ptr(std::move(value)), name(std::move(name)), help(std::move(help)) {}
    /**
     * @brief Constructs an option from a long name, short name, a description, and a value.
     */
    option(std::string name, char alias, std::string help = "", value_type value = constant(true)):
        ptr(std::move(value)), name(std::move(name)), help(std::move(help)), alias(alias) {}

    /**
     * @brief Constructs an option from a short name, description and value.
     */
    option(char alias, std::string help = "", value_type value = constant(true)):
        ptr(std::move(value)), help(std::move(help)), alias(alias) {}

    /**
     * @brief Copy constructor
     */
    option(const option& other):
        ptr(other.ptr == nullptr ? nullptr : other.ptr->clone()),
        name(other.name), help(other.help), alias(other.alias) {}

    /**
     * @brief Copy assignment
     */
    option& operator=(const option& other) {
        ptr = other.ptr == nullptr ? nullptr : other.ptr->clone();
        name = other.name;
        help = other.help;
        alias = other.alias;
        return *this;
    }

    /**
     * @brief Move constructor
     */
    option(option&&) = default;

    /**
     * @brief Move assignment
     */
    option& operator=(option&&) = default;

    /**
     * @brief Destructor
     */
    ~option() = default;

    /**
     * @brief Checks if the option accepts a value.
     */
    bool takes_value() const noexcept {
        return ptr != nullptr && ptr->nargs > 0;
    }

    /**
     * @brief Returns the number of arguments expected by the value.
     * @return Returns the number of arguments expected by the value.
     * If no value is expected, i.e. #takes_value is false, then 0 is
     * returned.
     */
    size_t nargs() const noexcept {
        return takes_value() ? ptr->nargs : 0;
    }

    //@{
    /**
     * @brief Checks if the option is represented by a long or short option.
     * @details Checks if the option is represented by a long or short option.
     * This function is typically used to avoid code repetition when handling
     * predicates dealing with checking for a long name or short name. This
     * is a member function rather than an `operator==` or `operator!=` to
     * disallow obfuscation and code duplication (e.g. `"help" == op` vs `op == "help"`).
     *
     * Example usage:
     *
     * @code
     * optparse::option x = { "help", 'h', "show message" };
     * x.is("help");    // true
     * x.is('h');       // true
     * x.is("stuff");   // false
     * @endcode
     *
     * @param arg Long or short option to check for.
     * @return `true` if the option can be represented by arg.
     */
    bool is(char arg) const noexcept {
        return alias == arg;
    }

    bool is(const std::string& arg) const noexcept {
        return name == arg;
    }
    //@}

    /**
     * @brief Retrieves the internal value of the option.
     * @details Retrieves the internal value of the option.
     * If the option has no value then an exception is thrown.
     *
     * @throws std::runtime_error Thrown if the option has not been parsed.
     * @throws std::invalid_argument Thrown for invalid casting or if the option has no value.
     * @return The internal value.
     */
    template<typename T>
    const T& get() const {
        if(ptr == nullptr) {
            throw std::invalid_argument("option does not take value");
        }
        auto val = dynamic_cast<typed_value<T>*>(ptr.get());

        if(val == nullptr) {
            throw std::invalid_argument("invalid cast for option");
        }
        return val->get();
    }

    /**
     * @brief Retrieves the internal value of the option or a reasonable default.
     * @details Retrieves the internal value of the option or a reasonable default.
     * If the option has no value then the default is returned. If the type is not
     * a valid cast then the default is returned.
     *
     * @return The internal value or a reasonable default.
     */
    template<typename T>
    const T& get_or(const typename std::remove_reference<T>::type& def) const noexcept {
        if(ptr == nullptr) {
            return def;
        }

        auto val = dynamic_cast<typed_value<T>*>(ptr.get());
        return val == nullptr ? def : val->get_or(def);
    }

    /**
     * @brief Checks if the option has gone through parsing.
     */
    bool is_active() const noexcept {
        return ptr != nullptr && ptr->is_active();
    }

    /**
     * @brief Retrieves the internal option's metavar member.
     * @details Retrieves the internal value's metavar member. If
     * #takes_value returns false, then an empty string is returned.
     * @return The internal value's metavar member.
     */
    std::string metavar() const noexcept {
        return takes_value() ? ptr->metavar : "";
    }
};
} // optparse
} // gears

#endif // GEARS_OPTPARSE_OPTION_HPP
<|endoftext|>


<commit_before>/*
	Copyright 2021 Jordi SUBIRANA

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
	Software, and to permit persons to whom the Software is furnished to do so, subject
	to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
	PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ATEMA_RENDERER_ENUMS_HPP
#define ATEMA_RENDERER_ENUMS_HPP

#include <Atema/Core/Flags.hpp>

namespace at
{
	enum class ImageFormat
	{
		// Color
		R8_UNORM,
		R8_SNORM,
		R8_USCALED,
		R8_SSCALED,
		R8_UINT,
		R8_SINT,
		R8_SRGB,

		RG8_UNORM,
		RG8_SNORM,
		RG8_USCALED,
		RG8_SSCALED,
		RG8_UINT,
		RG8_SINT,
		RG8_SRGB,

		RGB8_UNORM,
		RGB8_SNORM,
		RGB8_USCALED,
		RGB8_SSCALED,
		RGB8_UINT,
		RGB8_SINT,
		RGB8_SRGB,

		BGR8_UNORM,
		BGR8_SNORM,
		BGR8_USCALED,
		BGR8_SSCALED,
		BGR8_UINT,
		BGR8_SINT,
		BGR8_SRGB,

		RGBA8_UNORM,
		RGBA8_SNORM,
		RGBA8_USCALED,
		RGBA8_SSCALED,
		RGBA8_UINT,
		RGBA8_SINT,
		RGBA8_SRGB,

		BGRA8_UNORM,
		BGRA8_SNORM,
		BGRA8_USCALED,
		BGRA8_SSCALED,
		BGRA8_UINT,
		BGRA8_SINT,
		BGRA8_SRGB,

		// DepthStencil
		D32F,
		D32F_S8U,
		D24U_S8U
	};

	inline bool hasDepth(ImageFormat format)
	{
		switch (format)
		{
		case ImageFormat::D32F:
		case ImageFormat::D32F_S8U:
		case ImageFormat::D24U_S8U:
		{
			return true;
		}
		default:
		{
			return false;
		}
		}

		return false;
	}

	inline bool hasStencil(ImageFormat format)
	{
		switch (format)
		{
		case ImageFormat::D32F_S8U:
		case ImageFormat::D24U_S8U:
		{
			return true;
		}
		default:
		{
			return false;
		}
		}

		return false;
	}

	enum class ImageSamples
	{
		S1,
		S2,
		S4,
		S8,
		S16,
		S32,
		S64,
		Max = S64
	};

	enum class ImageTiling
	{
		Optimal, // Implementation dependent
		Linear // Laid out in memory to allow user access
	};

	enum class ImageUsage
	{
		RenderTarget = 0x0001,
		ShaderInput = 0x0002,
		TransferSrc = 0x0004,
		TransferDst = 0x0008,

		All = RenderTarget | ShaderInput | TransferDst | TransferSrc
	};

	ATEMA_DECLARE_FLAGS(ImageUsage);

	enum class ImageLayout
	{
		Undefined,
		Attachment,
		ShaderInput,
		TransferSrc,
		TransferDst,
		Present,

		All
	};

	enum class AttachmentLoading
	{
		Undefined,
		Clear,
		Load
	};

	enum class AttachmentStoring
	{
		Undefined,
		Store
	};

	enum class PrimitiveTopology
	{
		PointList,
		LineList,
		LineStrip,
		TriangleList,
		TriangleStrip,
		TriangleFan,
		LineListAdjacency,
		LineStripAdjacency,
		TriangleListAdjacency,
		TriangleStripAdjacency,
		PatchList
	};

	enum class PolygonMode
	{
		Fill,
		Line,
		Point
	};

	enum class CullMode
	{
		None = 0x0000,
		Front = 0x0001,
		Back = 0x0002,
		All = Front | Back
	};

	ATEMA_DECLARE_FLAGS(CullMode);

	enum class FrontFace
	{
		Clockwise,
		CounterClockwise
	};

	enum class BlendOperation
	{
		Add,
		Subtract,
		ReverseSubtract,
		Min,
		Max
	};

	enum class BlendFactor
	{
		Zero,
		One,
		SrcColor,
		OneMinusSrcColor,
		DstColor,
		OneMinusDstColor,
		SrcAlpha,
		OneMinusSrcAlpha,
		DstAlpha,
		OneMinusDstAlpha,
		ConstantColor,
		OneMinusConstantColor,
		ConstantAlpha,
		OneMinusConstantAlpha
	};

	enum class CompareOperation
	{
		Never,
		Less,
		Equal,
		LessOrEqual,
		Greater,
		NotEqual,
		GreaterOrEqual,
		Always
	};

	enum class StencilOperation
	{
		Keep,
		Zero,
		Replace,
		IncrementAndClamp,
		DecrementAndClamp,
		Invert,
		IncrementAndWrap,
		DecrementAndWrap
	};

	enum class DescriptorType
	{
		Sampler,
		CombinedImageSampler,
		SampledImage,
		StorageImage,
		UniformTexelBuffer,
		StorageTexelBuffer,
		UniformBuffer,
		StorageBuffer,
		UniformBufferDynamic,
		StorageBufferDynamic,
		InputAttachment
	};

	enum class ShaderStage
	{
		Vertex = 0x0001,
		TessellationControl = 0x0002,
		TessellationEvaluation = 0x0004,
		Geometry = 0x0008,
		Fragment = 0x0010,
		Compute = 0x0020,

		AllGraphics = Vertex | TessellationControl | TessellationEvaluation | Geometry | Fragment,
		All = 0xFFFF
	};

	ATEMA_DECLARE_FLAGS(ShaderStage);
}

#endif
<commit_msg>Renderer - Enums - PipelineStage<commit_after>/*
	Copyright 2021 Jordi SUBIRANA

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
	Software, and to permit persons to whom the Software is furnished to do so, subject
	to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
	PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ATEMA_RENDERER_ENUMS_HPP
#define ATEMA_RENDERER_ENUMS_HPP

#include <Atema/Core/Flags.hpp>

namespace at
{
	enum class ImageFormat
	{
		// Color
		R8_UNORM,
		R8_SNORM,
		R8_USCALED,
		R8_SSCALED,
		R8_UINT,
		R8_SINT,
		R8_SRGB,

		RG8_UNORM,
		RG8_SNORM,
		RG8_USCALED,
		RG8_SSCALED,
		RG8_UINT,
		RG8_SINT,
		RG8_SRGB,

		RGB8_UNORM,
		RGB8_SNORM,
		RGB8_USCALED,
		RGB8_SSCALED,
		RGB8_UINT,
		RGB8_SINT,
		RGB8_SRGB,

		BGR8_UNORM,
		BGR8_SNORM,
		BGR8_USCALED,
		BGR8_SSCALED,
		BGR8_UINT,
		BGR8_SINT,
		BGR8_SRGB,

		RGBA8_UNORM,
		RGBA8_SNORM,
		RGBA8_USCALED,
		RGBA8_SSCALED,
		RGBA8_UINT,
		RGBA8_SINT,
		RGBA8_SRGB,

		BGRA8_UNORM,
		BGRA8_SNORM,
		BGRA8_USCALED,
		BGRA8_SSCALED,
		BGRA8_UINT,
		BGRA8_SINT,
		BGRA8_SRGB,

		// DepthStencil
		D32F,
		D32F_S8U,
		D24U_S8U
	};

	inline bool hasDepth(ImageFormat format)
	{
		switch (format)
		{
		case ImageFormat::D32F:
		case ImageFormat::D32F_S8U:
		case ImageFormat::D24U_S8U:
		{
			return true;
		}
		default:
		{
			return false;
		}
		}

		return false;
	}

	inline bool hasStencil(ImageFormat format)
	{
		switch (format)
		{
		case ImageFormat::D32F_S8U:
		case ImageFormat::D24U_S8U:
		{
			return true;
		}
		default:
		{
			return false;
		}
		}

		return false;
	}

	enum class ImageSamples
	{
		S1,
		S2,
		S4,
		S8,
		S16,
		S32,
		S64,
		Max = S64
	};

	enum class ImageTiling
	{
		Optimal, // Implementation dependent
		Linear // Laid out in memory to allow user access
	};

	enum class ImageUsage
	{
		RenderTarget = 0x0001,
		ShaderInput = 0x0002,
		TransferSrc = 0x0004,
		TransferDst = 0x0008,

		All = RenderTarget | ShaderInput | TransferDst | TransferSrc
	};

	ATEMA_DECLARE_FLAGS(ImageUsage);

	enum class ImageLayout
	{
		Undefined,
		Attachment,
		ShaderInput,
		TransferSrc,
		TransferDst,
		Present,

		All
	};

	enum class AttachmentLoading
	{
		Undefined,
		Clear,
		Load
	};

	enum class AttachmentStoring
	{
		Undefined,
		Store
	};

	enum class PrimitiveTopology
	{
		PointList,
		LineList,
		LineStrip,
		TriangleList,
		TriangleStrip,
		TriangleFan,
		LineListAdjacency,
		LineStripAdjacency,
		TriangleListAdjacency,
		TriangleStripAdjacency,
		PatchList
	};

	enum class PolygonMode
	{
		Fill,
		Line,
		Point
	};

	enum class CullMode
	{
		None = 0x0000,
		Front = 0x0001,
		Back = 0x0002,
		All = Front | Back
	};

	ATEMA_DECLARE_FLAGS(CullMode);

	enum class FrontFace
	{
		Clockwise,
		CounterClockwise
	};

	enum class BlendOperation
	{
		Add,
		Subtract,
		ReverseSubtract,
		Min,
		Max
	};

	enum class BlendFactor
	{
		Zero,
		One,
		SrcColor,
		OneMinusSrcColor,
		DstColor,
		OneMinusDstColor,
		SrcAlpha,
		OneMinusSrcAlpha,
		DstAlpha,
		OneMinusDstAlpha,
		ConstantColor,
		OneMinusConstantColor,
		ConstantAlpha,
		OneMinusConstantAlpha
	};

	enum class CompareOperation
	{
		Never,
		Less,
		Equal,
		LessOrEqual,
		Greater,
		NotEqual,
		GreaterOrEqual,
		Always
	};

	enum class StencilOperation
	{
		Keep,
		Zero,
		Replace,
		IncrementAndClamp,
		DecrementAndClamp,
		Invert,
		IncrementAndWrap,
		DecrementAndWrap
	};

	enum class DescriptorType
	{
		Sampler,
		CombinedImageSampler,
		SampledImage,
		StorageImage,
		UniformTexelBuffer,
		StorageTexelBuffer,
		UniformBuffer,
		StorageBuffer,
		UniformBufferDynamic,
		StorageBufferDynamic,
		InputAttachment
	};

	enum class ShaderStage
	{
		Vertex = 0x0001,
		TessellationControl = 0x0002,
		TessellationEvaluation = 0x0004,
		Geometry = 0x0008,
		Fragment = 0x0010,
		Compute = 0x0020,

		AllGraphics = Vertex | TessellationControl | TessellationEvaluation | Geometry | Fragment,
		All = 0xFFFF
	};

	ATEMA_DECLARE_FLAGS(ShaderStage);

	enum class PipelineStage
	{
		TopOfPipe = 0x0001,
		DrawIndirect = 0x0002,
		VertexInput = 0x0004,
		VertexShader = 0x0008,
		TessellationControl = 0x0010,
		TessellationEvaluation = 0x0020,
		GeometryShader = 0x0040,
		FragmentShader = 0x0080,
		EarlyFragmentTests = 0x0100,
		LateFragmentTests = 0x0200,
		ColorAttachmentOutput = 0x0400,
		ComputeShader = 0x0800,
		Transfer = 0x1000,
		BottomOfPipe = 0x2000,
		Host = 0x4000
	};

	ATEMA_DECLARE_FLAGS(PipelineStage);
}

#endif
<|endoftext|>


<commit_before>#include "xml.h"

#include <cstring>
#include <iostream>
#include <string>

#include "../leanify.h"
#include "../utils.h"
#include "base64.h"

using std::cout;
using std::endl;
using std::string;

Xml::Xml(void *p, size_t s /*= 0*/) : Format(p, s)
{
    pugi::xml_parse_result result = doc_.load_buffer(fp_, size_, pugi::parse_default | pugi::parse_declaration | pugi::parse_doctype | pugi::parse_ws_pcdata_single);
    is_valid_ = result;
    encoding_ = result.encoding;
}

namespace
{

void TraverseElements(pugi::xml_node node, std::function<void(pugi::xml_node)> callback)
{
    // cannot use ranged loop here because we need to store the next_sibling before recursion so that if child was removed the loop won't be terminated
    for (pugi::xml_node child = node.first_child(), next; child; child = next)
    {
        next = child.next_sibling();
        TraverseElements(child, callback);
    }

    callback(node);
}

struct xml_memory_writer : pugi::xml_writer
{
    uint8_t *p_write;

    void write(const void* data, size_t size) override
    {
        memcpy(p_write, data, size);
        p_write += size;
    }
};

} // namespace

size_t Xml::Leanify(size_t size_leanified /*= 0*/)
{

    // if the XML is fb2 file
    if (doc_.child("FictionBook"))
    {
        if (is_verbose)
        {
            cout << "FB2 detected." << endl;
        }
        if (depth < max_depth)
        {
            depth++;

            pugi::xml_node root = doc_.child("FictionBook");

            // iterate through all binary element
            for (pugi::xml_node binary = root.child("binary"), next; binary; binary = next)
            {
                next = binary.next_sibling("binary");
                pugi::xml_attribute id = binary.attribute("id");
                if (id == nullptr || id.value() == nullptr || id.value()[0] == 0)
                {
                    root.remove_child(binary);
                    continue;
                }

                PrintFileName(id.value());

                const char *base64_data = binary.child_value();
                if (base64_data == nullptr)
                {
                    cout << "No data found." << endl;
                    continue;
                }
                size_t base64_len = strlen(base64_data);
                // copy to a new location because base64_data is const
                char *new_base64_data = new char[base64_len + 1];
                memcpy(new_base64_data, base64_data, base64_len);

                Base64 b64(new_base64_data, base64_len);
                size_t new_base64_len = b64.Leanify();

                if (new_base64_len < base64_len)
                {
                    new_base64_data[new_base64_len] = 0;
                    binary.text() = new_base64_data;
                }

                delete[] new_base64_data;
            }
            depth--;
        }
    }
    else if (doc_.child("svg"))
    {
        if (is_verbose)
        {
            cout << "SVG detected." << endl;
        }

        // remove XML declaration and doctype
        for (pugi::xml_node child = doc_.first_child(), next; child; child = next)
        {
            next = child.next_sibling();
            if (child.type() == pugi::node_declaration || child.type() == pugi::node_doctype)
            {
                doc_.remove_child(child);
            }
        }

        TraverseElements(doc_.child("svg"), [](pugi::xml_node node)
        {
            for (pugi::xml_attribute attr = node.first_attribute(), next; attr; attr = next)
            {
                next = attr.next_attribute();
                const char* value = attr.value();
                // remove empty attribute
                if (value == nullptr || *value == 0)
                {
                    node.remove_attribute(attr);
                    continue;
                }

                // shrink spaces and newlines in attribute
                // also removes preceding and trailing spaces
                string new_value;
                while (*value)
                {
                    if (*value == ' ' || *value == '\n' || *value == '\t')
                    {
                        do
                        {
                            value++;
                        }
                        while (*value == ' ' || *value == '\n' || *value == '\t');
                        if (*value == 0)
                        {
                            break;
                        }
                        new_value += ' ';
                    }
                    new_value += *value++;
                }
                attr = new_value.c_str() + (new_value[0] == ' ' ? 1 : 0);
            }

            // remove empty text element and container element
            const char* name = node.name();
            if (node.first_child() == nullptr)
            {
                if (strcmp(name, "text") == 0 ||
                    strcmp(name, "tspan") == 0 ||
                    strcmp(name, "a") == 0 ||
                    strcmp(name, "defs") == 0 ||
                    strcmp(name, "g") == 0 ||
                    strcmp(name, "marker") == 0 ||
                    strcmp(name, "mask") == 0 ||
                    strcmp(name, "missing-glyph") == 0 ||
                    strcmp(name, "pattern") == 0 ||
                    strcmp(name, "switch") == 0 ||
                    strcmp(name, "symbol") == 0)
                {
                    node.parent().remove_child(node);
                    return;
                }
            }

            if (strcmp(name, "tref") == 0 && node.attribute("xlink:href") == nullptr)
            {
                node.parent().remove_child(node);
                return;
            }

            if (strcmp(name, "metadata") == 0)
            {
                node.parent().remove_child(node);
                return;
            }
        });
    }

    // print leanified XML to memory
    xml_memory_writer writer;
    fp_ -= size_leanified;
    writer.p_write = fp_;
    doc_.save(writer, nullptr, pugi::format_raw | pugi::format_no_declaration, encoding_);
    size_ = writer.p_write - fp_;
    return size_;
}
<commit_msg>XML: Remove whitespace only single pcdata node if xml:space="preserve" is not set #3<commit_after>#include "xml.h"

#include <cstring>
#include <iostream>
#include <string>

#include "../leanify.h"
#include "../utils.h"
#include "base64.h"

using std::cout;
using std::endl;
using std::string;

Xml::Xml(void *p, size_t s /*= 0*/) : Format(p, s)
{
    pugi::xml_parse_result result = doc_.load_buffer(fp_, size_, pugi::parse_default | pugi::parse_declaration | pugi::parse_doctype | pugi::parse_ws_pcdata_single);
    is_valid_ = result;
    encoding_ = result.encoding;
}

namespace
{

// shrink spaces and newlines, also removes preceding and trailing spaces
string ShrinkSpace(const char* value)
{
    string new_value;
    while (*value)
    {
        if (*value == ' ' || *value == '\n' || *value == '\t')
        {
            do
            {
                value++;
            } while (*value == ' ' || *value == '\n' || *value == '\t');
            if (*value == 0)
            {
                break;
            }
            new_value += ' ';
        }
        new_value += *value++;
    }
    if (!new_value.empty() && new_value[0] == ' ')
    {
        new_value.erase(0, 1);
    }
    return new_value;
}

void TraverseElements(pugi::xml_node node, std::function<void(pugi::xml_node)> callback)
{
    // cannot use ranged loop here because we need to store the next_sibling before recursion so that if child was removed the loop won't be terminated
    for (pugi::xml_node child = node.first_child(), next; child; child = next)
    {
        next = child.next_sibling();
        TraverseElements(child, callback);
    }

    callback(node);
}

// Remove single PCData only contains whitespace if xml:space="preserve" is not set.
void RemovePCDataSingle(pugi::xml_node node, bool xml_space_preserve)
{
    xml_space_preserve |= strcmp(node.attribute("xml:space").value(), "preserve") == 0;
    if (xml_space_preserve)
    {
        return;
    }
    pugi::xml_node pcdata = node.first_child();
    if (pcdata.first_child() == nullptr &&
        pcdata.type() == pugi::node_pcdata &&
        pcdata.next_sibling() == nullptr)
    {
        if (ShrinkSpace(pcdata.value()).empty())
        {
            node.remove_child(pcdata);
        }
        return;
    }
    for (pugi::xml_node child : node.children())
    {
        RemovePCDataSingle(child, xml_space_preserve);
    }
}

struct xml_memory_writer : pugi::xml_writer
{
    uint8_t *p_write;

    void write(const void* data, size_t size) override
    {
        memcpy(p_write, data, size);
        p_write += size;
    }
};

} // namespace

size_t Xml::Leanify(size_t size_leanified /*= 0*/)
{
    RemovePCDataSingle(doc_, false);

    // if the XML is fb2 file
    if (doc_.child("FictionBook"))
    {
        if (is_verbose)
        {
            cout << "FB2 detected." << endl;
        }
        if (depth < max_depth)
        {
            depth++;

            pugi::xml_node root = doc_.child("FictionBook");

            // iterate through all binary element
            for (pugi::xml_node binary = root.child("binary"), next; binary; binary = next)
            {
                next = binary.next_sibling("binary");
                pugi::xml_attribute id = binary.attribute("id");
                if (id == nullptr || id.value() == nullptr || id.value()[0] == 0)
                {
                    root.remove_child(binary);
                    continue;
                }

                PrintFileName(id.value());

                const char *base64_data = binary.child_value();
                if (base64_data == nullptr)
                {
                    cout << "No data found." << endl;
                    continue;
                }
                size_t base64_len = strlen(base64_data);
                // copy to a new location because base64_data is const
                char *new_base64_data = new char[base64_len + 1];
                memcpy(new_base64_data, base64_data, base64_len);

                Base64 b64(new_base64_data, base64_len);
                size_t new_base64_len = b64.Leanify();

                if (new_base64_len < base64_len)
                {
                    new_base64_data[new_base64_len] = 0;
                    binary.text() = new_base64_data;
                }

                delete[] new_base64_data;
            }
            depth--;
        }
    }
    else if (doc_.child("svg"))
    {
        if (is_verbose)
        {
            cout << "SVG detected." << endl;
        }

        // remove XML declaration and doctype
        for (pugi::xml_node child = doc_.first_child(), next; child; child = next)
        {
            next = child.next_sibling();
            if (child.type() == pugi::node_declaration || child.type() == pugi::node_doctype)
            {
                doc_.remove_child(child);
            }
        }

        TraverseElements(doc_.child("svg"), [](pugi::xml_node node)
        {
            for (pugi::xml_attribute attr = node.first_attribute(), next; attr; attr = next)
            {
                next = attr.next_attribute();
                const char* value = attr.value();
                // remove empty attribute
                if (value == nullptr || *value == 0)
                {
                    node.remove_attribute(attr);
                    continue;
                }

                attr = ShrinkSpace(value).c_str();
            }

            // remove empty text element and container element
            const char* name = node.name();
            if (node.first_child() == nullptr)
            {
                if (strcmp(name, "text") == 0 ||
                    strcmp(name, "tspan") == 0 ||
                    strcmp(name, "a") == 0 ||
                    strcmp(name, "defs") == 0 ||
                    strcmp(name, "g") == 0 ||
                    strcmp(name, "marker") == 0 ||
                    strcmp(name, "mask") == 0 ||
                    strcmp(name, "missing-glyph") == 0 ||
                    strcmp(name, "pattern") == 0 ||
                    strcmp(name, "switch") == 0 ||
                    strcmp(name, "symbol") == 0)
                {
                    node.parent().remove_child(node);
                    return;
                }
            }

            if (strcmp(name, "tref") == 0 && node.attribute("xlink:href") == nullptr)
            {
                node.parent().remove_child(node);
                return;
            }

            if (strcmp(name, "metadata") == 0)
            {
                node.parent().remove_child(node);
                return;
            }
        });
    }

    // print leanified XML to memory
    xml_memory_writer writer;
    fp_ -= size_leanified;
    writer.p_write = fp_;
    doc_.save(writer, nullptr, pugi::format_raw | pugi::format_no_declaration, encoding_);
    size_ = writer.p_write - fp_;
    return size_;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QDebug>
#include <qmediaobject.h>
#include <qmediacontrol.h>
#include <qmediaservice.h>
#include <qmediarecordercontrol.h>
#include <qmediarecorder.h>
#include <qaudioendpointselector.h>
#include <qvideodevicecontrol.h>
#include <qaudioencodercontrol.h>
#include <qmediacontainercontrol.h>
#include <qvideoencodercontrol.h>
#include <QtMultimedia/qaudioformat.h>
#include <qaudiocapturesource.h>

#define QTRY_COMPARE(a,e)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if ((a) == (e)) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QCOMPARE(a, e)

#define QTRY_VERIFY(a)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if (a) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QVERIFY(a)

QTM_USE_NAMESPACE
class tst_QMediaRecorder: public QObject
{
    Q_OBJECT

public slots:
    void initTestCase();
    void cleanupTestCase();

private slots:
    void testAudioSink();
    void testAudioRecord();
    void testAudioEndPointSelector();
    void testAudioEncoderControl();
    void testMediaFormatsControl();
    void testDefaultVideoEncodingSettings();
//    void testDefaultAudioEncodingSettings();
    void testVideoEncoderControl();
    void testEncodingSettings();

private:
    QUrl recordPath(QDir outputDir);

    QAudioEncoderControl *audioEncoder;
    QAudioEndpointSelector *audioEndpoint;
    QMediaRecorder  *capture;
    QMediaRecorder  *audiocapture;
    QAudioCaptureSource *captureSource;
};

void tst_QMediaRecorder::initTestCase()
{
    qRegisterMetaType<QtMobility::QMediaRecorder::State>("QMediaRecorder::State");
    qRegisterMetaType<QtMobility::QMediaRecorder::Error>("QMediaRecorder::Error");

    captureSource = new QAudioCaptureSource;
    audiocapture = new QMediaRecorder(captureSource);

    audioEndpoint = qobject_cast<QAudioEndpointSelector*>(audiocapture->service()->control(QAudioEndpointSelector_iid));
    audioEncoder = qobject_cast<QAudioEncoderControl*>(audiocapture->service()->control(QAudioEncoderControl_iid));
}

void tst_QMediaRecorder::cleanupTestCase()
{
    delete audiocapture;
    delete captureSource;
    delete capture;
}

QUrl tst_QMediaRecorder::recordPath(QDir outputDir)
{
    int lastImage = 0;
    foreach( QString fileName, outputDir.entryList(QStringList() << "testclip_*.mpg") ) {
        int imgNumber = fileName.mid(5, fileName.size()-9).toInt();
        lastImage = qMax(lastImage, imgNumber);
    }

    QUrl location(QDir::toNativeSeparators(outputDir.canonicalPath()+QString("/testclip_%1.mpg").arg(lastImage+1,4,10,QLatin1Char('0'))));
    return location;
}

void tst_QMediaRecorder::testAudioSink()
{
    audiocapture->setOutputLocation(QUrl("test.tmp"));
    QUrl s = audiocapture->outputLocation();
    QCOMPARE(s.toString(), QString("test.tmp"));
}

void tst_QMediaRecorder::testAudioRecord()
{
}

void tst_QMediaRecorder::testAudioEndPointSelector()
{
    QSignalSpy audioSignal(audioEndpoint,SIGNAL(activeEndpointChanged(QString)));
    QVERIFY(audioEndpoint->availableEndpoints().count() == 1);
    QVERIFY(audioEndpoint->defaultEndpoint().compare("MMF") == 0);
    audioEndpoint->setActiveEndpoint("device2");
    QVERIFY(audioEndpoint->activeEndpoint().compare("device2") == 0);
    QVERIFY(audioSignal.count() == 1);
    QVERIFY(audioEndpoint->endpointDescription("device2").compare("") == 0);
}

void tst_QMediaRecorder::testAudioEncoderControl()
{
    QStringList codecs = audiocapture->supportedAudioCodecs();
    QVERIFY(codecs.count() == 1);
    QVERIFY(audiocapture->audioCodecDescription("audio/wav") == "WAV Write Format");
    QStringList options = audioEncoder->supportedEncodingOptions("audio/wav");
    QCOMPARE(options.count(), 0);
    QVERIFY(audioEncoder->encodingOption("audio/wav","bitrate").toInt() == -1);
    audioEncoder->setEncodingOption("audio/wav", "bitrate", QString("vbr"));
    QCOMPARE(audioEncoder->encodingOption("audio/wav","bitrate").toInt(), -1);
    QCOMPARE(audiocapture->supportedAudioSampleRates(), QList<int>() << 44100);
}

void tst_QMediaRecorder::testMediaFormatsControl()
{
    //videocontainer types
    QCOMPARE(capture->supportedContainers(), QStringList() << "video/3gpp" << "video/mp4" << "video/3gpp2");
    QCOMPARE(capture->containerDescription("video/3gpp"), QString("3GPP File Format"));
    QCOMPARE(capture->containerDescription("video/mp4"), QString("MPEG-4 File Format"));
    QCOMPARE(capture->containerDescription("video/3gpp2"), QString("3GPP2 File Format"));
    //audioocontainer types
    QCOMPARE(audiocapture->supportedContainers(), QStringList() << "audio/wav" << "audio/pcm");
    QCOMPARE(audiocapture->containerDescription("audio/pcm"), QString("WAV file format"));
    QCOMPARE(audiocapture->containerDescription("audio/x-wav"), QString("RAW file format"));
//    QCOMPARE(capture->containerDescription("mp3"), QString("MP3 format"));
//    QCOMPARE(capture->containerDescription("ogg"), QString());
}

void tst_QMediaRecorder::testDefaultVideoEncodingSettings()
{
    QVideoEncoderSettings videoSettings = capture->videoSettings();
    QCOMPARE(videoSettings.codec(), QString("video/H263-2000"));
    QCOMPARE(videoSettings.bitRate(), -1);
    QCOMPARE(videoSettings.resolution(), QSize(176, 144));
    QCOMPARE(videoSettings.frameRate(), 15.0);
    QCOMPARE(videoSettings.quality(), QtMedia::LowQuality);
//    QCOMPARE(videoSettings.encodingMode(), QtMedia::ConstantQualityEncoding);

    QString format = capture->containerMimeType();
    QCOMPARE(format, QString("video/3gpp"));
}
/*
void tst_QMediaRecorder::testDefaultAudioEncodingSettings()
{
  QAudioEncoderSettings audioSettings = capture->audioSettings();
    QCOMPARE(audioSettings.codec(), QString("audio/pcm"));
    QCOMPARE(audioSettings.bitRate(), 128*1024);
    QCOMPARE(audioSettings.sampleRate(), -1);
    QCOMPARE(audioSettings.quality(), QtMedia::NormalQuality);
    QCOMPARE(audioSettings.channelCount(), -1);

    QCOMPARE(audioSettings.encodingMode(), QtMedia::ConstantQualityEncoding);

}*/

void tst_QMediaRecorder::testVideoEncoderControl()
{
    bool continuous = false;
    QList<QSize> sizes = capture->supportedResolutions(QVideoEncoderSettings(), &continuous);
    QCOMPARE(sizes.count(), 3);
    QCOMPARE(continuous, false);

    QList<qreal> rates = capture->supportedFrameRates(QVideoEncoderSettings(), &continuous);
    QCOMPARE(rates.count(), 1);
    QCOMPARE(continuous, false);

    QStringList vCodecs = capture->supportedVideoCodecs();
    QVERIFY(vCodecs.count() == 3);
    QCOMPARE(capture->videoCodecDescription("video/mp4"), QString("MPEG-4 File Format"));
    QCOMPARE(capture->videoCodecDescription("video/3gpp"), QString("3GPP File Format"));
    QCOMPARE(capture->videoCodecDescription("video/3ggp2"), QString("3GPP2 File Format"));

    QStringList options = videoEncoder->supportedEncodingOptions("video/mp4");
    QCOMPARE(options.count(), 4);

    QVERIFY(videoEncoder->encodingOption("video/mp4","bitrate") == QVariant(-1));
    videoEncoder->setEncodingOption("video/mp4", "bitrate", QVariant(128000));
    QCOMPARE(videoEncoder->encodingOption("video/mp4","bitrate"), QVariant(128000));
    videoEncoder->setEncodingOption("video/mp4", "bitrate", QVariant(-1));
}

void tst_QMediaRecorder::testEncodingSettings()
{
    QAudioEncoderSettings audioSettings;
    QVideoEncoderSettings videoSettings;
    QString format;
/*
    audioSettings.setCodec("audio/mpeg");
    audioSettings.setSampleRate(44100);
    audioSettings.setBitRate(256*1024);
    audioSettings.setQuality(QtMedia::HighQuality);
    audioSettings.setEncodingMode(QtMedia::AverageBitRateEncoding);*/

    videoSettings.setCodec("video/3gpp");
    videoSettings.setBitRate(800);
    videoSettings.setFrameRate(24*1024);
    videoSettings.setResolution(QSize(800,600));
    videoSettings.setQuality(QtMedia::HighQuality);
//    audioSettings.setEncodingMode(QtMedia::TwoPassEncoding);

    format = QString("mov");

    capture->setEncodingSettings(audioSettings,videoSettings,format);

    QCOMPARE(capture->audioSettings(), audioSettings);
    QCOMPARE(capture->videoSettings(), videoSettings);
    QCOMPARE(capture->containerMimeType(), format);
}

QTEST_MAIN(tst_QMediaRecorder)

#include "tst_qmediarecorder_s60.moc"
<commit_msg>Remove camera/video elements from tests This unit test now only tests elements of audio recording<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QDebug>
#include <qmediaobject.h>
#include <qmediacontrol.h>
#include <qmediaservice.h>
#include <qmediarecordercontrol.h>
#include <qmediarecorder.h>
#include <qaudioendpointselector.h>
#include <qaudioencodercontrol.h>
#include <qmediacontainercontrol.h>
#include <QtMultimedia/qaudioformat.h>
#include <qaudiocapturesource.h>

#define QTRY_COMPARE(a,e)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if ((a) == (e)) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QCOMPARE(a, e)

#define QTRY_VERIFY(a)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if (a) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QVERIFY(a)

QTM_USE_NAMESPACE
class tst_QMediaRecorder: public QObject
{
    Q_OBJECT

public slots:
    void initTestCase();
    void cleanupTestCase();

private slots:
    void testAudioSink();
    void testAudioRecord();
    void testAudioEndPointSelector();
    void testAudioEncoderControl();
    void testMediaFormatsControl();
//    void testDefaultAudioEncodingSettings();

private:

    QAudioEncoderControl *audioEncoder;
    QAudioEndpointSelector *audioEndpoint;
    QMediaRecorder  *audiocapture;
    QAudioCaptureSource *captureSource;
};

void tst_QMediaRecorder::initTestCase()
{
    qRegisterMetaType<QtMobility::QMediaRecorder::State>("QMediaRecorder::State");
    qRegisterMetaType<QtMobility::QMediaRecorder::Error>("QMediaRecorder::Error");

    captureSource = new QAudioCaptureSource;
    audiocapture = new QMediaRecorder(captureSource);

    audioEndpoint = qobject_cast<QAudioEndpointSelector*>(audiocapture->service()->control(QAudioEndpointSelector_iid));
    audioEncoder = qobject_cast<QAudioEncoderControl*>(audiocapture->service()->control(QAudioEncoderControl_iid));
}

void tst_QMediaRecorder::cleanupTestCase()
{
    delete audiocapture;
    delete captureSource;
    delete capture;
}

void tst_QMediaRecorder::testAudioSink()
{
    audiocapture->setOutputLocation(QUrl("test.tmp"));
    QUrl s = audiocapture->outputLocation();
    QCOMPARE(s.toString(), QString("test.tmp"));
}

void tst_QMediaRecorder::testAudioRecord()
{
}

void tst_QMediaRecorder::testAudioEndPointSelector()
{
    QSignalSpy audioSignal(audioEndpoint,SIGNAL(activeEndpointChanged(QString)));
    QVERIFY(audioEndpoint->availableEndpoints().count() == 1);
    QVERIFY(audioEndpoint->defaultEndpoint().compare("MMF") == 0);
    audioEndpoint->setActiveEndpoint("device2");
    QVERIFY(audioEndpoint->activeEndpoint().compare("device2") == 0);
    QVERIFY(audioSignal.count() == 1);
    QVERIFY(audioEndpoint->endpointDescription("device2").compare("") == 0);
}

void tst_QMediaRecorder::testAudioEncoderControl()
{
    QStringList codecs = audiocapture->supportedAudioCodecs();
    QVERIFY(codecs.count() == 1);
    QVERIFY(audiocapture->audioCodecDescription("audio/wav") == "WAV Write Format");
    QStringList options = audioEncoder->supportedEncodingOptions("audio/wav");
    QCOMPARE(options.count(), 0);
    QVERIFY(audioEncoder->encodingOption("audio/wav","bitrate").toInt() == -1);
    audioEncoder->setEncodingOption("audio/wav", "bitrate", QString("vbr"));
    QCOMPARE(audioEncoder->encodingOption("audio/wav","bitrate").toInt(), -1);
    QCOMPARE(audiocapture->supportedAudioSampleRates(), QList<int>() << 44100);
}

void tst_QMediaRecorder::testMediaFormatsControl()
{
    //audioocontainer types
    QCOMPARE(audiocapture->supportedContainers(), QStringList() << "audio/wav" << "audio/pcm");
    QCOMPARE(audiocapture->containerDescription("audio/pcm"), QString("WAV file format"));
    QCOMPARE(audiocapture->containerDescription("audio/x-wav"), QString("RAW file format"));
}

/*
void tst_QMediaRecorder::testDefaultAudioEncodingSettings()
{
  QAudioEncoderSettings audioSettings = capture->audioSettings();
    QCOMPARE(audioSettings.codec(), QString("audio/pcm"));
    QCOMPARE(audioSettings.bitRate(), 128*1024);
    QCOMPARE(audioSettings.sampleRate(), -1);
    QCOMPARE(audioSettings.quality(), QtMedia::NormalQuality);
    QCOMPARE(audioSettings.channelCount(), -1);

    QCOMPARE(audioSettings.encodingMode(), QtMedia::ConstantQualityEncoding);

}*/

QTEST_MAIN(tst_QMediaRecorder)

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


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <algorithm>
#include <cassert>

#include "IECore/VectorTraits.h"

namespace IECore
{

template<class BoundIterator>
class BoundedKDTree<BoundIterator>::AxisSort
{
	public :
		AxisSort( unsigned int axis ) : m_axis( axis )
		{
		}

		bool operator() ( BoundIterator i, BoundIterator j )
		{
			return i->center()[m_axis] < j->center()[m_axis];
		}

	private :
		const unsigned int m_axis;
};

template<class BoundIterator>
class BoundedKDTree<BoundIterator>::Node
{
	public :

		Node() : m_cutAxisAndLeaf(0)
		{
			m_bound.makeEmpty();
			m_perm.first = 0;
			m_perm.last = 0;
		}

		inline void makeLeaf( PermutationIterator permFirst, PermutationIterator permLast )
		{
			m_cutAxisAndLeaf = 255;
			m_perm.first = &(*permFirst);
			m_perm.last = &(*permLast);
		}

		inline void makeBranch( unsigned char cutAxis )
		{
			m_cutAxisAndLeaf = cutAxis;
		}

		inline bool isLeaf() const
		{
			return m_cutAxisAndLeaf==255;
		}

		inline BoundIterator *permFirst() const
		{
			assert( isLeaf() );

			return m_perm.first;
		}

		inline BoundIterator *permLast() const
		{
			assert( isLeaf() );

			return m_perm.last;
		}

		inline bool isBranch() const
		{
			return m_cutAxisAndLeaf!=255;
		}

		inline unsigned char cutAxis() const
		{
			assert( isBranch() );

			return m_cutAxisAndLeaf;
		}

		inline Bound &bound()
		{
			return m_bound;
		}

		inline const Bound &bound() const
		{
			return m_bound;
		}

		static NodeIndex rootIndex()
		{
			return 1;
		}

		static NodeIndex lowChildIndex( NodeIndex index )
		{
			return index * 2;
		}

		static NodeIndex highChildIndex( NodeIndex index )
		{
			return index * 2 + 1;
		}

	private :

		unsigned char m_cutAxisAndLeaf;

		Bound m_bound;

		struct {
			BoundIterator *first;
			BoundIterator *last;
		} m_perm;

};

template<class BoundIterator>
unsigned char BoundedKDTree<BoundIterator>::majorAxis( PermutationConstIterator permFirst, PermutationConstIterator permLast )
{
	BaseType min, max;
	for( unsigned char i=0; i<VectorTraits<BaseType>::dimensions(); i++ ) {
		min[i] = Imath::limits<typename BaseType::BaseType>::max();
		max[i] = Imath::limits<typename BaseType::BaseType>::min();
	}

	/// \todo Find a better cutting axis
	for( PermutationConstIterator it=permFirst; it!=permLast; it++ )
	{
		BaseType center = (*it)->center();

		for( unsigned char i=0; i<VectorTraits<BaseType>::dimensions(); i++ )
		{
			if( center[i] < min[i] )
			{
				min[i] = center[i];
			}
			if( center[i] > max[i] )
			{
				max[i] = center[i];
			}
		}

	}
	unsigned char major = 0;
	BaseType size = max - min;
	for( unsigned char i=1; i<VectorTraits<BaseType>::dimensions(); i++ )
	{
		if( size[i] > size[major] )
		{
			major = i;
		}
	}
	return major;
}

template<class BoundIterator>
void BoundedKDTree<BoundIterator>::bound( NodeIndex nodeIndex  )
{
	assert( nodeIndex < m_nodes.size() );

	Node &node = m_nodes[nodeIndex];

	assert( node.bound().isEmpty() );

	if( node.isLeaf() )
	{
		BoundIterator *permLast = node.permLast();
		for( BoundIterator *perm = node.permFirst(); perm!=permLast; perm++ )
		{
			node.bound().extendBy( **perm );
		}
	}
	else
	{
		assert( node.isBranch() );

		assert( Node::lowChildIndex( nodeIndex ) < m_nodes.size() );
		assert( Node::highChildIndex( nodeIndex ) < m_nodes.size() );

		bound( Node::lowChildIndex( nodeIndex ) );
		bound( Node::highChildIndex( nodeIndex ) );
		node.bound().extendBy( m_nodes[Node::lowChildIndex( nodeIndex )].bound() );
		node.bound().extendBy( m_nodes[Node::highChildIndex( nodeIndex )].bound() );
	}
}

template<class BoundIterator>
void BoundedKDTree<BoundIterator>::build( NodeIndex nodeIndex, PermutationIterator permFirst, PermutationIterator permLast )
{
	// make room for the new node
	if( nodeIndex>=m_nodes.size() )
	{
		m_nodes.resize( nodeIndex+1 );
	}

	assert( nodeIndex < m_nodes.size() );

	Node &node = m_nodes[nodeIndex];

	if( permLast - permFirst > m_maxLeafSize )
	{
		unsigned int cutAxis = majorAxis( permFirst, permLast );
		PermutationIterator permMid = permFirst  + (permLast - permFirst)/2;
		std::nth_element( permFirst, permMid, permLast, AxisSort( cutAxis ) );

		// insert node
		node.makeBranch( cutAxis );

		build( Node::lowChildIndex( nodeIndex ), permFirst, permMid );
		build( Node::highChildIndex( nodeIndex ), permMid, permLast );
	}
	else
	{
		// leaf node
		node.makeLeaf( permFirst, permLast );
	}
}

template<class BoundIterator>
BoundedKDTree<BoundIterator>::BoundedKDTree( BoundIterator first, BoundIterator last, int maxLeafSize )
	:	m_maxLeafSize( maxLeafSize ), m_lastBound( last )
{
	m_perm.resize( last - first );
	unsigned int i=0;
	for( BoundIterator it=first; it!=last; it++ )
	{
		m_perm[i++] = it;
	}

	build( Node::rootIndex(), m_perm.begin(), m_perm.end() );
	bound( Node::rootIndex() );
}

template<class BoundIterator>
template<typename S>
unsigned int BoundedKDTree<BoundIterator>::intersectingBounds( const S &b, std::vector<BoundIterator> &bounds ) const
{
	bounds.clear();

	intersectingBoundsWalk(Node::rootIndex(), b, bounds );

	return bounds.size();
}

template<class BoundIterator>
template<typename S>
void BoundedKDTree<BoundIterator>::intersectingBoundsWalk(  NodeIndex nodeIndex, const S &b, std::vector<BoundIterator> &bounds ) const
{
	const Node &node = m_nodes[nodeIndex];
	if( node.isLeaf() )
	{
		BoundIterator *permLast = node.permLast();
		for( BoundIterator *perm = node.permFirst(); perm!=permLast; perm++ )
		{
			const Bound &bb = **perm;

			if ( bb.intersects(b) )
			{
				bounds.push_back( *perm );
			}
		}
	}
	else
	{
		NodeIndex firstChild = Node::highChildIndex( nodeIndex );
		if ( m_nodes[firstChild].bound().intersects(b) )
		{
			intersectingBoundsWalk( firstChild, b, bounds );
		}
		NodeIndex secondChild = Node::lowChildIndex( nodeIndex );
		if ( m_nodes[secondChild].bound().intersects(b) )
		{
			intersectingBoundsWalk( secondChild, b, bounds );
		}
	}
}

} // namespace IECore
<commit_msg>Better use of BoxTraits and VectorOps for reusability<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <algorithm>
#include <cassert>

#include "IECore/VectorTraits.h"
#include "IECore/VectorOps.h"

namespace IECore
{

template<class BoundIterator>
class BoundedKDTree<BoundIterator>::AxisSort
{
	public :
		AxisSort( unsigned int axis ) : m_axis( axis )
		{
		}

		bool operator() ( BoundIterator i, BoundIterator j )
		{
			return VectorTraits< BaseType >::get( BoxTraits<Bound>::center(*i), m_axis)
				< VectorTraits< BaseType >::get( BoxTraits<Bound>::center(*j), m_axis);
		}

	private :
		const unsigned int m_axis;
};

template<class BoundIterator>
class BoundedKDTree<BoundIterator>::Node
{
	public :

		Node() : m_cutAxisAndLeaf(0)
		{
			BoxTraits<Bound>::makeEmpty( m_bound );
			m_perm.first = 0;
			m_perm.last = 0;
		}

		inline void makeLeaf( PermutationIterator permFirst, PermutationIterator permLast )
		{
			m_cutAxisAndLeaf = 255;
			m_perm.first = &(*permFirst);
			m_perm.last = &(*permLast);
		}

		inline void makeBranch( unsigned char cutAxis )
		{
			m_cutAxisAndLeaf = cutAxis;
		}

		inline bool isLeaf() const
		{
			return m_cutAxisAndLeaf==255;
		}

		inline BoundIterator *permFirst() const
		{
			assert( isLeaf() );

			return m_perm.first;
		}

		inline BoundIterator *permLast() const
		{
			assert( isLeaf() );

			return m_perm.last;
		}

		inline bool isBranch() const
		{
			return m_cutAxisAndLeaf!=255;
		}

		inline unsigned char cutAxis() const
		{
			assert( isBranch() );

			return m_cutAxisAndLeaf;
		}

		inline Bound &bound()
		{
			return m_bound;
		}

		inline const Bound &bound() const
		{
			return m_bound;
		}

		static NodeIndex rootIndex()
		{
			return 1;
		}

		static NodeIndex lowChildIndex( NodeIndex index )
		{
			return index * 2;
		}

		static NodeIndex highChildIndex( NodeIndex index )
		{
			return index * 2 + 1;
		}

	private :

		unsigned char m_cutAxisAndLeaf;

		Bound m_bound;

		struct {
			BoundIterator *first;
			BoundIterator *last;
		} m_perm;

};

template<class BoundIterator>
unsigned char BoundedKDTree<BoundIterator>::majorAxis( PermutationConstIterator permFirst, PermutationConstIterator permLast )
{
	BaseType min, max;
	vecSetAll( min, Imath::limits<typename BaseType::BaseType>::max() );
	vecSetAll( max, Imath::limits<typename BaseType::BaseType>::min() );

	/// \todo Find a better cutting axis
	for( PermutationConstIterator it=permFirst; it!=permLast; it++ )
	{
		BaseType center = BoxTraits<Bound>::center(**it);

		for( unsigned char i=0; i<VectorTraits<BaseType>::dimensions(); i++ )
		{
			if( VectorTraits<BaseType>::get(center, i) < VectorTraits<BaseType>::get(min, i) )
			{
				VectorTraits<BaseType>::set(min, i, VectorTraits<BaseType>::get(center, i) );
			}
			if( VectorTraits<BaseType>::get(center, i) > VectorTraits<BaseType>::get(min, i) )
			{
				VectorTraits<BaseType>::set(max, i, VectorTraits<BaseType>::get(center, i) );
			}
		}

	}
	unsigned char major = 0;
	BaseType size;
	vecSub( max, min, size );
	for( unsigned char i=1; i<VectorTraits<BaseType>::dimensions(); i++ )
	{
		if( VectorTraits<BaseType>::get(size, i) > VectorTraits<BaseType>::get(size, major) )
		{
			major = i;
		}
	}
	return major;
}

template<class BoundIterator>
void BoundedKDTree<BoundIterator>::bound( NodeIndex nodeIndex  )
{
	assert( nodeIndex < m_nodes.size() );

	Node &node = m_nodes[nodeIndex];

	assert( BoxTraits<Bound>::isEmpty( node.bound() ) );

	if( node.isLeaf() )
	{
		BoundIterator *permLast = node.permLast();
		for( BoundIterator *perm = node.permFirst(); perm!=permLast; perm++ )
		{
			BoxTraits<Bound>::extendBy( node.bound(), **perm );
		}
	}
	else
	{
		assert( node.isBranch() );

		assert( Node::lowChildIndex( nodeIndex ) < m_nodes.size() );
		assert( Node::highChildIndex( nodeIndex ) < m_nodes.size() );

		bound( Node::lowChildIndex( nodeIndex ) );
		bound( Node::highChildIndex( nodeIndex ) );
		BoxTraits<Bound>::extendBy( node.bound(), m_nodes[Node::lowChildIndex( nodeIndex )].bound() );
		BoxTraits<Bound>::extendBy( node.bound(), m_nodes[Node::highChildIndex( nodeIndex )].bound() );
	}
}

template<class BoundIterator>
void BoundedKDTree<BoundIterator>::build( NodeIndex nodeIndex, PermutationIterator permFirst, PermutationIterator permLast )
{
	// make room for the new node
	if( nodeIndex>=m_nodes.size() )
	{
		m_nodes.resize( nodeIndex+1 );
	}

	assert( nodeIndex < m_nodes.size() );

	Node &node = m_nodes[nodeIndex];

	if( permLast - permFirst > m_maxLeafSize )
	{
		unsigned int cutAxis = majorAxis( permFirst, permLast );
		PermutationIterator permMid = permFirst  + (permLast - permFirst)/2;
		std::nth_element( permFirst, permMid, permLast, AxisSort( cutAxis ) );

		// insert node
		node.makeBranch( cutAxis );

		build( Node::lowChildIndex( nodeIndex ), permFirst, permMid );
		build( Node::highChildIndex( nodeIndex ), permMid, permLast );
	}
	else
	{
		// leaf node
		node.makeLeaf( permFirst, permLast );
	}
}

template<class BoundIterator>
BoundedKDTree<BoundIterator>::BoundedKDTree( BoundIterator first, BoundIterator last, int maxLeafSize )
	:	m_maxLeafSize( maxLeafSize ), m_lastBound( last )
{
	m_perm.resize( last - first );
	unsigned int i=0;
	for( BoundIterator it=first; it!=last; it++ )
	{
		m_perm[i++] = it;
	}

	build( Node::rootIndex(), m_perm.begin(), m_perm.end() );
	bound( Node::rootIndex() );
}

template<class BoundIterator>
template<typename S>
unsigned int BoundedKDTree<BoundIterator>::intersectingBounds( const S &b, std::vector<BoundIterator> &bounds ) const
{
	bounds.clear();

	intersectingBoundsWalk(Node::rootIndex(), b, bounds );

	return bounds.size();
}

template<class BoundIterator>
template<typename S>
void BoundedKDTree<BoundIterator>::intersectingBoundsWalk(  NodeIndex nodeIndex, const S &b, std::vector<BoundIterator> &bounds ) const
{
	const Node &node = m_nodes[nodeIndex];
	if( node.isLeaf() )
	{
		BoundIterator *permLast = node.permLast();
		for( BoundIterator *perm = node.permFirst(); perm!=permLast; perm++ )
		{
			const Bound &bb = **perm;

			if ( BoxTraits<Bound>::intersects( bb, b ) )
			{
				bounds.push_back( *perm );
			}
		}
	}
	else
	{
		NodeIndex firstChild = Node::highChildIndex( nodeIndex );
		if ( BoxTraits<Bound>::intersects( m_nodes[firstChild].bound(), b) )
		{
			intersectingBoundsWalk( firstChild, b, bounds );
		}
		NodeIndex secondChild = Node::lowChildIndex( nodeIndex );
		if ( BoxTraits<Bound>::intersects( m_nodes[secondChild].bound(), b) )
		{
			intersectingBoundsWalk( secondChild, b, bounds );
		}
	}
}

} // namespace IECore
<|endoftext|>