<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <test/bootstrapfixture.hxx>
#include <unotest/macros_test.hxx>

#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/table/XTableChartsSupplier.hpp>
#include <com/sun/star/table/XTableCharts.hpp>
#include <com/sun/star/table/XTableChart.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>

#include <comphelper/processfactory.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;

class Chart2ImportTest : public test::BootstrapFixture, public unotest::MacrosTest
{
public:
    void Fdo60083();

    virtual void setUp();
    virtual void tearDown();

    CPPUNIT_TEST_SUITE(Chart2ImportTest);
    CPPUNIT_TEST(Fdo60083);
    CPPUNIT_TEST_SUITE_END();

private:
    void load( const char* pDir, const char* pName );

    Reference< chart2::XChartDocument > getChartDocFromSheet( sal_Int32 nSheet, uno::Reference< lang::XComponent > xComponent );
    Reference< chart2::XDataSeries > getDataSeriesFromDoc( Reference< chart2::XChartDocument > xChartDoc,
            sal_Int32 nDataSeries, sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0 );

    Reference< lang::XComponent > mxComponent;
};

// error bar import
// split method up into smaller chunks for more detailed tests
void Chart2ImportTest::Fdo60083()
{
    load("/chart2/qa/extras/data/ods/", "error_bar_simple.ods");
    uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
    CPPUNIT_ASSERT(xChartDoc.is());

    Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
    CPPUNIT_ASSERT( xDataSeries.is() );

    Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xPropSet.is() );

    // test that y error bars are there
    Reference< beans::XPropertySet > xErrorBarYProps;
    xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps;
    CPPUNIT_ASSERT(xErrorBarYProps.is());

    // test that x error bars are not imported
    Reference< beans::XPropertySet > xErrorBarXProps;
    xPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarXProps;
    CPPUNIT_ASSERT(!xErrorBarXProps.is());
}

Reference< chart2::XChartDocument > Chart2ImportTest::getChartDocFromSheet( sal_Int32 nSheet, uno::Reference< lang::XComponent > xComponent )
{
    // let us assume that we only have one chart per sheet

    uno::Reference< sheet::XSpreadsheetDocument > xDoc(xComponent, UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xDoc.is());

    uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xIA.is());

    uno::Reference< table::XTableChartsSupplier > xChartSupplier( xIA->getByIndex(nSheet), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xChartSupplier.is());

    uno::Reference< table::XTableCharts > xCharts = xChartSupplier->getCharts();
    CPPUNIT_ASSERT(xCharts.is());

    uno::Reference< container::XIndexAccess > xIACharts(xCharts, UNO_QUERY_THROW);
    uno::Reference< table::XTableChart > xChart( xIACharts->getByIndex(0), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xChart.is());

    uno::Reference< document::XEmbeddedObjectSupplier > xEmbObjectSupplier(xChart, UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xEmbObjectSupplier.is());

    uno::Reference< lang::XComponent > xChartComp( xEmbObjectSupplier->getEmbeddedObject(), UNO_QUERY_THROW );
    CPPUNIT_ASSERT(xChartComp.is());

    uno::Reference< chart2::XChartDocument > xChartDoc ( xChartComp, UNO_QUERY_THROW );

    CPPUNIT_ASSERT(xChartDoc.is());
    return xChartDoc;
}

Reference< chart2::XDataSeries > Chart2ImportTest::getDataSeriesFromDoc( uno::Reference< chart2::XChartDocument > xChartDoc,
                                                                sal_Int32 nDataSeries, sal_Int32 nChartType, sal_Int32 nCooSys )
{
    CPPUNIT_ASSERT( xChartDoc.is() );

    Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram();
    CPPUNIT_ASSERT( xDiagram.is() );

    Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xCooSysContainer.is() );

    Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems());
    CPPUNIT_ASSERT( xCooSysSequence.getLength() > nCooSys );

    Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[nCooSys], UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xChartTypeContainer.is() );

    Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() );
    CPPUNIT_ASSERT( xChartTypeSequence.getLength() > nChartType );

    Reference< chart2::XDataSeriesContainer > xDataSequenceContainer( xChartTypeSequence[nChartType], UNO_QUERY_THROW );
    CPPUNIT_ASSERT ( xDataSequenceContainer.is() );

    Sequence< Reference< chart2::XDataSeries > > xSeriesSequence( xDataSequenceContainer->getDataSeries() );
    CPPUNIT_ASSERT( xSeriesSequence.getLength() > nDataSeries );

    Reference< chart2::XDataSeries > xSeries = xSeriesSequence[nDataSeries];

    return xSeries;
}

void Chart2ImportTest::load( const char* pDir, const char* pName )
{
    mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName), "com.sun.star.sheet.SpreadsheetDocument");
    CPPUNIT_ASSERT(mxComponent.is());
}

void Chart2ImportTest::setUp()
{
    test::BootstrapFixture::setUp();

    mxDesktop.set( com::sun::star::frame::Desktop::create( comphelper::getComponentContext(getMultiServiceFactory()) ) );
}

void Chart2ImportTest::tearDown()
{
    if(mxComponent.is())
        mxComponent->dispose();

    test::BootstrapFixture::tearDown();

}

CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>improve chart2 import test<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <test/bootstrapfixture.hxx>
#include <unotest/macros_test.hxx>

#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/table/XTableChartsSupplier.hpp>
#include <com/sun/star/table/XTableCharts.hpp>
#include <com/sun/star/table/XTableChart.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>

#include <comphelper/processfactory.hxx>

using namespace com::sun::star;
using namespace com::sun::star::uno;

class Chart2ImportTest : public test::BootstrapFixture, public unotest::MacrosTest
{
public:
    void Fdo60083();

    virtual void setUp();
    virtual void tearDown();

    CPPUNIT_TEST_SUITE(Chart2ImportTest);
    CPPUNIT_TEST(Fdo60083);
    CPPUNIT_TEST_SUITE_END();

private:
    void load( const char* pDir, const char* pName );

    Reference< chart2::XChartDocument > getChartDocFromSheet( sal_Int32 nSheet, uno::Reference< lang::XComponent > xComponent );
    Reference< chart2::XDataSeries > getDataSeriesFromDoc( Reference< chart2::XChartDocument > xChartDoc,
            sal_Int32 nDataSeries, sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0 );

    Reference< lang::XComponent > mxComponent;
};

// error bar import
// split method up into smaller chunks for more detailed tests
void Chart2ImportTest::Fdo60083()
{
    load("/chart2/qa/extras/data/ods/", "error_bar_simple.ods");
    uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
    CPPUNIT_ASSERT(xChartDoc.is());

    Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
    CPPUNIT_ASSERT( xDataSeries.is() );

    Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xPropSet.is() );

    // test that y error bars are there
    Reference< beans::XPropertySet > xErrorBarYProps;
    xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps;
    CPPUNIT_ASSERT(xErrorBarYProps.is());
    {
        sal_Int32 nErrorBarStyle;
        xErrorBarYProps->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle;
        CPPUNIT_ASSERT_EQUAL(nErrorBarStyle, static_cast<sal_Int32>(chart::ErrorBarStyle::RELATIVE));

        double nVal;
        xErrorBarYProps->getPropertyValue("PositiveError") >>= nVal;
        CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0, nVal, 1e-8);

        xErrorBarYProps->getPropertyValue("NegativeError") >>= nVal;
        CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0, nVal, 1e-8);

        sal_Bool bVal;
        xErrorBarYProps->getPropertyValue("ShowPositiveError") >>= bVal;
        CPPUNIT_ASSERT_EQUAL(static_cast<bool>(bVal), true);

        xErrorBarYProps->getPropertyValue("ShowNegativeError") >>= bVal;
        CPPUNIT_ASSERT_EQUAL(static_cast<bool>(bVal), true);
    }

    // test that x error bars are not imported
    Reference< beans::XPropertySet > xErrorBarXProps;
    xPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarXProps;
    CPPUNIT_ASSERT(!xErrorBarXProps.is());
}

Reference< chart2::XChartDocument > Chart2ImportTest::getChartDocFromSheet( sal_Int32 nSheet, uno::Reference< lang::XComponent > xComponent )
{
    // let us assume that we only have one chart per sheet

    uno::Reference< sheet::XSpreadsheetDocument > xDoc(xComponent, UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xDoc.is());

    uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xIA.is());

    uno::Reference< table::XTableChartsSupplier > xChartSupplier( xIA->getByIndex(nSheet), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xChartSupplier.is());

    uno::Reference< table::XTableCharts > xCharts = xChartSupplier->getCharts();
    CPPUNIT_ASSERT(xCharts.is());

    uno::Reference< container::XIndexAccess > xIACharts(xCharts, UNO_QUERY_THROW);
    uno::Reference< table::XTableChart > xChart( xIACharts->getByIndex(0), UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xChart.is());

    uno::Reference< document::XEmbeddedObjectSupplier > xEmbObjectSupplier(xChart, UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xEmbObjectSupplier.is());

    uno::Reference< lang::XComponent > xChartComp( xEmbObjectSupplier->getEmbeddedObject(), UNO_QUERY_THROW );
    CPPUNIT_ASSERT(xChartComp.is());

    uno::Reference< chart2::XChartDocument > xChartDoc ( xChartComp, UNO_QUERY_THROW );

    CPPUNIT_ASSERT(xChartDoc.is());
    return xChartDoc;
}

Reference< chart2::XDataSeries > Chart2ImportTest::getDataSeriesFromDoc( uno::Reference< chart2::XChartDocument > xChartDoc,
                                                                sal_Int32 nDataSeries, sal_Int32 nChartType, sal_Int32 nCooSys )
{
    CPPUNIT_ASSERT( xChartDoc.is() );

    Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram();
    CPPUNIT_ASSERT( xDiagram.is() );

    Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xCooSysContainer.is() );

    Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems());
    CPPUNIT_ASSERT( xCooSysSequence.getLength() > nCooSys );

    Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[nCooSys], UNO_QUERY_THROW );
    CPPUNIT_ASSERT( xChartTypeContainer.is() );

    Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() );
    CPPUNIT_ASSERT( xChartTypeSequence.getLength() > nChartType );

    Reference< chart2::XDataSeriesContainer > xDataSequenceContainer( xChartTypeSequence[nChartType], UNO_QUERY_THROW );
    CPPUNIT_ASSERT ( xDataSequenceContainer.is() );

    Sequence< Reference< chart2::XDataSeries > > xSeriesSequence( xDataSequenceContainer->getDataSeries() );
    CPPUNIT_ASSERT( xSeriesSequence.getLength() > nDataSeries );

    Reference< chart2::XDataSeries > xSeries = xSeriesSequence[nDataSeries];

    return xSeries;
}

void Chart2ImportTest::load( const char* pDir, const char* pName )
{
    mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName), "com.sun.star.sheet.SpreadsheetDocument");
    CPPUNIT_ASSERT(mxComponent.is());
}

void Chart2ImportTest::setUp()
{
    test::BootstrapFixture::setUp();

    mxDesktop.set( com::sun::star::frame::Desktop::create( comphelper::getComponentContext(getMultiServiceFactory()) ) );
}

void Chart2ImportTest::tearDown()
{
    if(mxComponent.is())
        mxComponent->dispose();

    test::BootstrapFixture::tearDown();

}

CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "sessiontreedelegate.h"
#include <QStyleOptionViewItem>
#include <QApplication>
#include <QPalette>
#include <QPainter>

SessionTreeDelegate::SessionTreeDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
}

void SessionTreeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    const bool topLevel = !index.parent().isValid();
    if (topLevel)
    {
        const bool selected = option.state & QStyle::State_Selected;
        if (!selected)
        {
            QLinearGradient gradient(option.rect.topLeft(), option.rect.bottomLeft());
            gradient.setColorAt(0.0, qApp->palette().color(QPalette::AlternateBase));
            gradient.setColorAt(1.0, qApp->palette().color(QPalette::Dark));
            painter->fillRect(option.rect, gradient);
        }
        else
        {
            const_cast<QStyleOptionViewItem&>(option).state &= ~QStyle::State_Selected;
            painter->fillRect(option.rect, qApp->palette().color(QPalette::Highlight));
        }

        QVector<QLine> lines;
        if (index.row() > 0)
            lines += QLine(option.rect.topLeft(), option.rect.topRight());
        lines += QLine(option.rect.bottomLeft(), option.rect.bottomRight());
        painter->setPen(qApp->palette().color(QPalette::Dark));
        painter->drawLines(lines);
    }

    QStyledItemDelegate::paint(painter, option, index);
}
<commit_msg>desktop ex: fine tune SessionTreeDelegate::paint()<commit_after>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "sessiontreedelegate.h"
#include <QStyleOptionViewItem>
#include <QApplication>
#include <QPalette>
#include <QPainter>

SessionTreeDelegate::SessionTreeDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
}

void SessionTreeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    const bool topLevel = !index.parent().isValid();
    if (topLevel)
    {
        const bool selected = option.state & QStyle::State_Selected;
        const_cast<QStyleOptionViewItem&>(option).state &= ~QStyle::State_Selected;

        QColor c1 = qApp->palette().color(QPalette::AlternateBase);
        QColor c2 = qApp->palette().color(QPalette::Dark);
        if (selected)
            qSwap(c1, c2);

        QLinearGradient gradient(option.rect.topLeft(), option.rect.bottomLeft());
        gradient.setColorAt(0.0, c1);
        gradient.setColorAt(1.0, c2);
        painter->fillRect(option.rect, gradient);

        QVector<QLine> lines;
        if (index.row() > 0)
            lines += QLine(option.rect.topLeft(), option.rect.topRight());
        lines += QLine(option.rect.bottomLeft(), option.rect.bottomRight());
        painter->setPen(qApp->palette().color(QPalette::Dark));
        painter->drawLines(lines);
    }

    QStyledItemDelegate::paint(painter, option, index);
}
<|endoftext|>


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

#include <hazelcast/client/HazelcastClient.h>
#include <hazelcast/client/EntryListener.h>

int main() {
    hazelcast::client::HazelcastClient hz;

    auto map = hz.getMap("somemap");

    auto listener = hazelcast::client::EntryListener()
        .onEntryAdded([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryAdded] " << event << std::endl;
        })
        .onEntryRemoved([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryRemoved] " << event << std::endl;
        })
        .onEntryUpdated([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryAdded] " << event << std::endl;
        })
        .onEntryEvicted([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryUpdated] " << event << std::endl;
        })
        .onEntryExpired([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryExpired] " << event << std::endl;
        })
        .onEntryMerged([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryMerged] " << event << std::endl;
        })
        .onMapEvicted([](const hazelcast::client::MapEvent &event) {
            std::cout << "[mapEvicted] " << event << std::endl;
        })
        .onMapCleared([](const hazelcast::client::MapEvent &event) {
            std::cout << "[mapCleared] " << event << std::endl;
        });

    std::string listenerId = map->addEntryListener(listener, true).get();

    std::cout << "EntryListener registered" << std::endl;

    // wait for modifymap executable to run
    std::this_thread::sleep_for(std::chrono::seconds(10));

    map->removeEntryListener(listenerId).get();

    // Continuous Query example
    // Register listener with predicate
    // Only listen events for entries with key >= 7
    listenerId = map->addEntryListener(listener, hazelcast::client::query::GreaterLessPredicate(hz,
            hazelcast::client::query::QueryConstants::KEY_ATTRIBUTE_NAME, 7, true, false), true).get();

    // wait for modifymap executable to run
    std::this_thread::sleep_for(std::chrono::seconds(10));

    map->removeEntryListener(listenerId).get();

    std::cout << "Finished" << std::endl;

    return 0;
}
<commit_msg>Fix example<commit_after>/*
 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <hazelcast/client/HazelcastClient.h>
#include <hazelcast/client/EntryListener.h>

hazelcast::client::EntryListener makeListener() {
    return hazelcast::client::EntryListener()
        .onEntryAdded([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryAdded] " << event << std::endl;
        })
        .onEntryRemoved([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryRemoved] " << event << std::endl;
        })
        .onEntryUpdated([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryAdded] " << event << std::endl;
        })
        .onEntryEvicted([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryUpdated] " << event << std::endl;
        })
        .onEntryExpired([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryExpired] " << event << std::endl;
        })
        .onEntryMerged([](const hazelcast::client::EntryEvent &event) {
            std::cout << "[entryMerged] " << event << std::endl;
        })
        .onMapEvicted([](const hazelcast::client::MapEvent &event) {
            std::cout << "[mapEvicted] " << event << std::endl;
        })
        .onMapCleared([](const hazelcast::client::MapEvent &event) {
            std::cout << "[mapCleared] " << event << std::endl;
        });
}

int main() {
    hazelcast::client::HazelcastClient hz;

    auto map = hz.getMap("somemap");

    std::string listenerId = map->addEntryListener(makeListener(), true).get();

    std::cout << "EntryListener registered" << std::endl;

    // wait for modifymap executable to run
    std::this_thread::sleep_for(std::chrono::seconds(10));

    map->removeEntryListener(listenerId).get();

    // Continuous Query example
    // Register listener with predicate
    // Only listen events for entries with key >= 7
    listenerId = map->addEntryListener(makeListener(), hazelcast::client::query::GreaterLessPredicate(hz,
            hazelcast::client::query::QueryConstants::KEY_ATTRIBUTE_NAME, 7, true, false), true).get();

    // wait for modifymap executable to run
    std::this_thread::sleep_for(std::chrono::seconds(10));

    map->removeEntryListener(listenerId).get();

    std::cout << "Finished" << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <cmath>
#include <ctime>
#include <cstdlib>

#include <pkmnsim/types/prng.hpp>

namespace pkmnsim
{
    uint32_t prng::_lcrng_seed;
    uint64_t prng::_gen5_lcrng_seed;
    uint32_t prng::_arng_seed;
    unsigned int prng::_mtrng_pos;
    uint32_t prng::_mtrng_seeds[];

    prng::prng()
    {
        srand( time(NULL) );

        _lcrng_seed = rand();
        _gen5_lcrng_seed = rand();

        _arng_seed = rand();

        for(int i = 0; i < 624; i++) _mtrng_seeds[i] = rand();
        _mtrng_pos = 0;
    }

    uint64_t prng::lcrng_next(uint32_t gen)
    {
        if(gen == 5)
        {
            uint64_t result = (0x5D588B656C078965 * _gen5_lcrng_seed) + 0x0000000000269EC3;
            _gen5_lcrng_seed = result;
            return result;
        }
        else
        {
            uint32_t result = (0x41C64E6D * _lcrng_seed) + 0x6073;
            _lcrng_seed = result;
            return result;
        }
    }

    uint32_t prng::arng_next()
    {
        uint32_t result = (0x6C078965 * _arng_seed) + 0x1;
        _arng_seed = result;
        return result;
    }

    uint32_t prng::mtrng_next()
    {
        uint32_t result = _mtrng_seeds[_mtrng_pos];

        if(_mtrng_pos == 623)
        {
            for(int i = 0; i < 624; i++) _mtrng_seeds[i] = rand();
            _mtrng_pos = 0;
        }
        else _mtrng_pos++;
        return result;
    }
} /* namespace pkmnsim */
<commit_msg>prng: better management of static members<commit_after>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <cmath>
#include <ctime>
#include <cstdlib>

#include <pkmnsim/types/prng.hpp>

namespace pkmnsim
{
    uint32_t prng::_lcrng_seed = rand();
    uint64_t prng::_gen5_lcrng_seed = rand();
    uint32_t prng::_arng_seed = rand();
    unsigned int prng::_mtrng_pos = 0;
    uint32_t prng::_mtrng_seeds[];

    prng::prng()
    {
        srand( time(NULL) );

        /*
         * If first index of MTRNG seed array is zero, assume it hasn't been
         * initialized.
         */
        if(_mtrng_seeds[0] == 0)
            for(int i = 0; i < 624; i++) _mtrng_seeds[i] = rand();
    }

    uint64_t prng::lcrng_next(uint32_t gen)
    {
        if(gen == 5)
        {
            uint64_t result = (0x5D588B656C078965 * _gen5_lcrng_seed) + 0x0000000000269EC3;
            _gen5_lcrng_seed = result;
            return result;
        }
        else
        {
            uint32_t result = (0x41C64E6D * _lcrng_seed) + 0x6073;
            _lcrng_seed = result;
            return result;
        }
    }

    uint32_t prng::arng_next()
    {
        uint32_t result = (0x6C078965 * _arng_seed) + 0x1;
        _arng_seed = result;
        return result;
    }

    uint32_t prng::mtrng_next()
    {
        uint32_t result = _mtrng_seeds[_mtrng_pos];

        if(_mtrng_pos == 623)
        {
            for(int i = 0; i < 624; i++) _mtrng_seeds[i] = rand();
            _mtrng_pos = 0;
        }
        else _mtrng_pos++;
        return result;
    }
} /* namespace pkmnsim */
<|endoftext|>


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

#include "chrome/browser/gtk/infobar_gtk.h"

#include <gtk/gtk.h>

#include "base/gfx/gtk_util.h"
#include "base/string_util.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"

namespace {

// TODO(estade): The background should be a gradient. For now we just use this
// solid color.
const GdkColor kBackgroundColor = GDK_COLOR_RGB(250, 230, 145);

// Border color (the top pixel of the infobar).
const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

// The total height of the info bar.
const int kInfoBarHeight = 37;

// Pixels between infobar elements.
const int kElementPadding = 5;

// Extra padding on either end of info bar.
const int kLeftPadding = 5;
const int kRightPadding = 5;

}

InfoBar::InfoBar(InfoBarDelegate* delegate)
    : container_(NULL),
      delegate_(delegate) {
  // Create |hbox_| and pad the sides.
  hbox_ = gtk_hbox_new(FALSE, kElementPadding);
  GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
      0, 0, kLeftPadding, kRightPadding);

  GtkWidget* bg_box = gtk_event_box_new();
  gtk_container_add(GTK_CONTAINER(padding), hbox_);
  gtk_container_add(GTK_CONTAINER(bg_box), padding);

  // Set the top border and background color.
  gtk_widget_modify_bg(bg_box, GTK_STATE_NORMAL, &kBackgroundColor);
  widget_.Own(gfx::CreateGtkBorderBin(bg_box, &kBorderColor,
                                      1, 0, 0, 0));
  gtk_widget_set_size_request(widget_.get(), -1, kInfoBarHeight);

  close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox_));
  g_signal_connect(G_OBJECT(close_button_->widget()), "clicked",
                   G_CALLBACK(OnCloseButton), this);

  g_object_set_data(G_OBJECT(widget_.get()), "info-bar", this);
}

InfoBar::~InfoBar() {
  widget_.Destroy();
}

void InfoBar::AnimateOpen() {
  // TODO(port): add animations. In the meantime just Open().
  NOTIMPLEMENTED();
  Open();
}

void InfoBar::Open() {
  gtk_widget_show_all(widget_.get());
}

void InfoBar::AnimateClose() {
  // TODO(port): add animations. In the meantime just Close().
  NOTIMPLEMENTED();
  Close();
}

void InfoBar::Close() {
  gtk_widget_hide(widget_.get());
}

void InfoBar::RemoveInfoBar() const {
  container_->RemoveDelegate(delegate_);
}

// static
void InfoBar::OnCloseButton(GtkWidget* button, InfoBar* info_bar) {
  info_bar->AnimateClose();
}

// AlertInfoBar ----------------------------------------------------------------

class AlertInfoBar : public InfoBar {
 public:
  AlertInfoBar(AlertInfoBarDelegate* delegate)
      : InfoBar(delegate) {
    std::wstring text = delegate->GetMessageText();
    GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str());

    SkBitmap* icon = delegate->GetIcon();
    GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
    GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
    gdk_pixbuf_unref(pixbuf);

    gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
  }
};

// LinkInfoBar -----------------------------------------------------------------

class LinkInfoBar : public InfoBar {
 public:
  LinkInfoBar(LinkInfoBarDelegate* delegate)
      : InfoBar(delegate) {
    // TODO(estade): remove these lines.
    NOTIMPLEMENTED();
    GtkWidget* label = gtk_label_new("LinkInfoBar not yet implemented. "
                                     "Check back later.");
    gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 10);
  }
};

// ConfirmInfoBar --------------------------------------------------------------

class ConfirmInfoBar : public AlertInfoBar {
 public:
  ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
      : AlertInfoBar(delegate) {
    NOTIMPLEMENTED();
  }
};

// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  return new AlertInfoBar(this);
}

// LinkInfoBarDelegate, InfoBarDelegate overrides: -----------------------------

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  return new LinkInfoBar(this);
}

// ConfirmInfoBarDelegate, InfoBarDelegate overrides: --------------------------

InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  return new ConfirmInfoBar(this);
}
<commit_msg>Linux: Hook up confirm info bar buttons. Session restore works.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/infobar_gtk.h"

#include <gtk/gtk.h>

#include "base/gfx/gtk_util.h"
#include "base/string_util.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"

namespace {

// TODO(estade): The background should be a gradient. For now we just use this
// solid color.
const GdkColor kBackgroundColor = GDK_COLOR_RGB(250, 230, 145);

// Border color (the top pixel of the infobar).
const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

// The total height of the info bar.
const int kInfoBarHeight = 37;

// Pixels between infobar elements.
const int kElementPadding = 5;

// Extra padding on either end of info bar.
const int kLeftPadding = 5;
const int kRightPadding = 5;

}

InfoBar::InfoBar(InfoBarDelegate* delegate)
    : container_(NULL),
      delegate_(delegate) {
  // Create |hbox_| and pad the sides.
  hbox_ = gtk_hbox_new(FALSE, kElementPadding);
  GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
      0, 0, kLeftPadding, kRightPadding);

  GtkWidget* bg_box = gtk_event_box_new();
  gtk_container_add(GTK_CONTAINER(padding), hbox_);
  gtk_container_add(GTK_CONTAINER(bg_box), padding);

  // Set the top border and background color.
  gtk_widget_modify_bg(bg_box, GTK_STATE_NORMAL, &kBackgroundColor);
  widget_.Own(gfx::CreateGtkBorderBin(bg_box, &kBorderColor,
                                      1, 0, 0, 0));
  gtk_widget_set_size_request(widget_.get(), -1, kInfoBarHeight);

  close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox_));
  g_signal_connect(close_button_->widget(), "clicked",
                   G_CALLBACK(OnCloseButton), this);

  g_object_set_data(G_OBJECT(widget_.get()), "info-bar", this);
}

InfoBar::~InfoBar() {
  widget_.Destroy();
}

void InfoBar::AnimateOpen() {
  // TODO(port): add animations. In the meantime just Open().
  NOTIMPLEMENTED();
  Open();
}

void InfoBar::Open() {
  gtk_widget_show_all(widget_.get());
}

void InfoBar::AnimateClose() {
  // TODO(port): add animations. In the meantime just Close().
  NOTIMPLEMENTED();
  Close();
}

void InfoBar::Close() {
  gtk_widget_hide(widget_.get());
}

void InfoBar::RemoveInfoBar() const {
  container_->RemoveDelegate(delegate_);
}

// static
void InfoBar::OnCloseButton(GtkWidget* button, InfoBar* info_bar) {
  info_bar->AnimateClose();
}

// AlertInfoBar ----------------------------------------------------------------

class AlertInfoBar : public InfoBar {
 public:
  AlertInfoBar(AlertInfoBarDelegate* delegate)
      : InfoBar(delegate) {
    std::wstring text = delegate->GetMessageText();
    GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str());

    SkBitmap* icon = delegate->GetIcon();
    GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
    GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
    gdk_pixbuf_unref(pixbuf);

    gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
  }
};

// LinkInfoBar -----------------------------------------------------------------

class LinkInfoBar : public InfoBar {
 public:
  LinkInfoBar(LinkInfoBarDelegate* delegate)
      : InfoBar(delegate) {
    // TODO(estade): remove these lines.
    NOTIMPLEMENTED();
    GtkWidget* label = gtk_label_new("LinkInfoBar not yet implemented. "
                                     "Check back later.");
    gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 10);
  }
};

// ConfirmInfoBar --------------------------------------------------------------

class ConfirmInfoBar : public AlertInfoBar {
 public:
  ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
      : AlertInfoBar(delegate) {
    AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
    AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK);
  }

 private:
  // Adds a button to the info bar by type. It will do nothing if the delegate
  // doesn't specify a button of the given type.
  void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) {
    if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) {
      GtkWidget* button = gtk_button_new_with_label(WideToUTF8(
          delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str());
      GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_end(GTK_BOX(centering_vbox), button, TRUE, FALSE, 0);
      gtk_box_pack_end(GTK_BOX(hbox_), centering_vbox, FALSE, FALSE, 0);
      g_signal_connect(button, "clicked",
                       G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
                                  OnOkButton : OnCancelButton),
                       this);
    }
  }

  static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
    if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel())
      info_bar->RemoveInfoBar();
  }

  static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
    if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept())
      info_bar->RemoveInfoBar();
  }
};

// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  return new AlertInfoBar(this);
}

// LinkInfoBarDelegate, InfoBarDelegate overrides: -----------------------------

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  return new LinkInfoBar(this);
}

// ConfirmInfoBarDelegate, InfoBarDelegate overrides: --------------------------

InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  return new ConfirmInfoBar(this);
}
<|endoftext|>


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

#include "chrome/browser/tabs/tab_finder.h"

#include "base/command_line.h"
#include "base/stl_util-inl.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_switches.h"
#include "content/browser/tab_contents/navigation_details.h"
#include "content/browser/tab_contents/navigation_entry.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_observer.h"
#include "content/common/notification_service.h"
#include "content/common/notification_source.h"
#include "content/common/notification_type.h"
#include "content/common/page_transition_types.h"
#include "content/common/view_messages.h"

class TabFinder::TabContentsObserverImpl : public TabContentsObserver {
 public:
  TabContentsObserverImpl(TabContents* tab, TabFinder* finder);
  virtual ~TabContentsObserverImpl();

  TabContents* tab_contents() { return TabContentsObserver::tab_contents(); }

  // TabContentsObserver overrides:
  virtual void DidNavigateAnyFramePostCommit(
      const content::LoadCommittedDetails& details,
      const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
  virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE;

 private:
  TabFinder* finder_;

  DISALLOW_COPY_AND_ASSIGN(TabContentsObserverImpl);
};

TabFinder::TabContentsObserverImpl::TabContentsObserverImpl(
    TabContents* tab,
    TabFinder* finder)
    : TabContentsObserver(tab),
      finder_(finder) {
}

TabFinder::TabContentsObserverImpl::~TabContentsObserverImpl() {
}

void TabFinder::TabContentsObserverImpl::DidNavigateAnyFramePostCommit(
    const content::LoadCommittedDetails& details,
    const ViewHostMsg_FrameNavigate_Params& params) {
  finder_->DidNavigateAnyFramePostCommit(tab_contents(), details, params);
}

void TabFinder::TabContentsObserverImpl::TabContentsDestroyed(
    TabContents* tab) {
  finder_->TabDestroyed(this);
  delete this;
}

// static
TabFinder* TabFinder::GetInstance() {
  return IsEnabled() ? Singleton<TabFinder>::get() : NULL;
}

// static
bool TabFinder::IsEnabled() {
  return CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kFocusExistingTabOnOpen);
}

TabContents* TabFinder::FindTab(Browser* browser,
                                const GURL& url,
                                Browser** existing_browser) {
  if (browser->profile()->IsOffTheRecord())
    return NULL;

  // If the current tab matches the url, ignore it and let the user reload the
  // existing tab.
  TabContents* selected_tab = browser->GetSelectedTabContents();
  if (TabMatchesURL(selected_tab, url))
    return NULL;

  // See if the current browser has a tab matching the specified url.
  TabContents* tab_in_browser = FindTabInBrowser(browser, url);
  if (tab_in_browser) {
    *existing_browser = browser;
    return tab_in_browser;
  }

  // Then check other browsers.
  for (BrowserList::const_iterator i = BrowserList::begin();
       i != BrowserList::end(); ++i) {
    if (!(*i)->profile()->IsOffTheRecord()) {
      tab_in_browser = FindTabInBrowser(*i, url);
      if (tab_in_browser) {
        *existing_browser = *i;
        return tab_in_browser;
      }
    }
  }

  return NULL;
}

void TabFinder::Observe(NotificationType type,
                        const NotificationSource& source,
                        const NotificationDetails& details) {
  DCHECK_EQ(type.value, NotificationType::TAB_PARENTED);

  // The tab was added to a browser. Query for its state now.
  NavigationController* controller =
      Source<NavigationController>(source).ptr();
  TrackTab(controller->tab_contents());
}

TabFinder::TabFinder() {
  registrar_.Add(this, NotificationType::TAB_PARENTED,
                 NotificationService::AllSources());
}

TabFinder::~TabFinder() {
  STLDeleteElements(&tab_contents_observers_);
}

void TabFinder::Init() {
  for (BrowserList::const_iterator i = BrowserList::begin();
       i != BrowserList::end(); ++i) {
    if (!(*i)->profile()->IsOffTheRecord())
      TrackBrowser(*i);
  }
}

void TabFinder::DidNavigateAnyFramePostCommit(
    TabContents* source,
    const content::LoadCommittedDetails& details,
    const ViewHostMsg_FrameNavigate_Params& params) {
  CancelRequestsFor(source);

  if (PageTransition::IsRedirect(params.transition)) {
    // If this is a redirect, we need to go to the db to get the start.
    FetchRedirectStart(source);
  } else if (params.redirects.size() > 1 ||
             params.redirects[0] != details.entry->url()) {
    tab_contents_to_url_[source] = params.redirects[0];
  }
}

bool TabFinder::TabMatchesURL(TabContents* tab_contents, const GURL& url) {
  if (tab_contents->GetURL() == url)
    return true;

  TabContentsToURLMap::const_iterator i =
      tab_contents_to_url_.find(tab_contents);
  return i != tab_contents_to_url_.end() && i->second == url;
}

TabContents* TabFinder::FindTabInBrowser(Browser* browser, const GURL& url) {
  if (!browser->is_type_tabbed())
    return NULL;

  for (int i = 0; i < browser->tab_count(); ++i) {
    if (TabMatchesURL(browser->GetTabContentsAt(i), url))
      return browser->GetTabContentsAt(i);
  }
  return NULL;
}

void TabFinder::TrackTab(TabContents* tab) {
  for (TabContentsObservers::const_iterator i = tab_contents_observers_.begin();
       i != tab_contents_observers_.end(); ++i) {
    if ((*i)->tab_contents() == tab) {
      // Already tracking the tab.
      return;
    }
  }
  TabContentsObserverImpl* observer = new TabContentsObserverImpl(tab, this);
  tab_contents_observers_.insert(observer);
  FetchRedirectStart(tab);
}

void TabFinder::TrackBrowser(Browser* browser) {
  for (int i = 0; i < browser->tab_count(); ++i)
    FetchRedirectStart(browser->GetTabContentsAt(i));
}

void TabFinder::TabDestroyed(TabContentsObserverImpl* observer) {
  DCHECK_GT(tab_contents_observers_.count(observer), 0u);
  tab_contents_observers_.erase(observer);
}

void TabFinder::CancelRequestsFor(TabContents* tab_contents) {
  if (tab_contents->profile()->IsOffTheRecord())
    return;

  tab_contents_to_url_.erase(tab_contents);

  HistoryService* history = tab_contents->profile()->GetHistoryService(
      Profile::EXPLICIT_ACCESS);
  if (history) {
    CancelableRequestProvider::Handle request_handle;
    if (callback_consumer_.GetFirstHandleForClientData(tab_contents,
                                                       &request_handle)) {
      history->CancelRequest(request_handle);
    }
  }
}

void TabFinder::FetchRedirectStart(TabContents* tab) {
  if (tab->profile()->IsOffTheRecord())
    return;

  NavigationEntry* committed_entry = tab->controller().GetLastCommittedEntry();
  if (!committed_entry || committed_entry->url().is_empty())
    return;

  HistoryService* history =tab->profile()->GetHistoryService(
      Profile::EXPLICIT_ACCESS);
  if (history) {
    CancelableRequestProvider::Handle request_handle =
        history->QueryRedirectsTo(
            committed_entry->url(),
            &callback_consumer_,
            NewCallback(this, &TabFinder::QueryRedirectsToComplete));
    callback_consumer_.SetClientData(history, request_handle, tab);
  }
}

void TabFinder::QueryRedirectsToComplete(HistoryService::Handle handle,
                                         GURL url,
                                         bool success,
                                         history::RedirectList* redirects) {
  if (success && !redirects->empty()) {
    TabContents* tab_contents =
        callback_consumer_.GetClientDataForCurrentRequest();
    DCHECK(tab_contents);
    tab_contents_to_url_[tab_contents] = redirects->back();
  }
}
<commit_msg>Make focus-existing-tab-on-open multi-profile-aware.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/tabs/tab_finder.h"

#include "base/command_line.h"
#include "base/stl_util-inl.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_switches.h"
#include "content/browser/tab_contents/navigation_details.h"
#include "content/browser/tab_contents/navigation_entry.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_observer.h"
#include "content/common/notification_service.h"
#include "content/common/notification_source.h"
#include "content/common/notification_type.h"
#include "content/common/page_transition_types.h"
#include "content/common/view_messages.h"

class TabFinder::TabContentsObserverImpl : public TabContentsObserver {
 public:
  TabContentsObserverImpl(TabContents* tab, TabFinder* finder);
  virtual ~TabContentsObserverImpl();

  TabContents* tab_contents() { return TabContentsObserver::tab_contents(); }

  // TabContentsObserver overrides:
  virtual void DidNavigateAnyFramePostCommit(
      const content::LoadCommittedDetails& details,
      const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
  virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE;

 private:
  TabFinder* finder_;

  DISALLOW_COPY_AND_ASSIGN(TabContentsObserverImpl);
};

TabFinder::TabContentsObserverImpl::TabContentsObserverImpl(
    TabContents* tab,
    TabFinder* finder)
    : TabContentsObserver(tab),
      finder_(finder) {
}

TabFinder::TabContentsObserverImpl::~TabContentsObserverImpl() {
}

void TabFinder::TabContentsObserverImpl::DidNavigateAnyFramePostCommit(
    const content::LoadCommittedDetails& details,
    const ViewHostMsg_FrameNavigate_Params& params) {
  finder_->DidNavigateAnyFramePostCommit(tab_contents(), details, params);
}

void TabFinder::TabContentsObserverImpl::TabContentsDestroyed(
    TabContents* tab) {
  finder_->TabDestroyed(this);
  delete this;
}

// static
TabFinder* TabFinder::GetInstance() {
  return IsEnabled() ? Singleton<TabFinder>::get() : NULL;
}

// static
bool TabFinder::IsEnabled() {
  return CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kFocusExistingTabOnOpen);
}

TabContents* TabFinder::FindTab(Browser* browser,
                                const GURL& url,
                                Browser** existing_browser) {
  if (browser->profile()->IsOffTheRecord())
    return NULL;

  // If the current tab matches the url, ignore it and let the user reload the
  // existing tab.
  TabContents* selected_tab = browser->GetSelectedTabContents();
  if (TabMatchesURL(selected_tab, url))
    return NULL;

  // See if the current browser has a tab matching the specified url.
  TabContents* tab_in_browser = FindTabInBrowser(browser, url);
  if (tab_in_browser) {
    *existing_browser = browser;
    return tab_in_browser;
  }

  // Then check other browsers.
  for (BrowserList::const_iterator i = BrowserList::begin();
       i != BrowserList::end(); ++i) {
    if (!(*i)->profile()->IsOffTheRecord() &&
         (*i)->profile()->IsSameProfile(browser->profile())) {
      tab_in_browser = FindTabInBrowser(*i, url);
      if (tab_in_browser) {
        *existing_browser = *i;
        return tab_in_browser;
      }
    }
  }

  return NULL;
}

void TabFinder::Observe(NotificationType type,
                        const NotificationSource& source,
                        const NotificationDetails& details) {
  DCHECK_EQ(type.value, NotificationType::TAB_PARENTED);

  // The tab was added to a browser. Query for its state now.
  NavigationController* controller =
      Source<NavigationController>(source).ptr();
  TrackTab(controller->tab_contents());
}

TabFinder::TabFinder() {
  registrar_.Add(this, NotificationType::TAB_PARENTED,
                 NotificationService::AllSources());
}

TabFinder::~TabFinder() {
  STLDeleteElements(&tab_contents_observers_);
}

void TabFinder::Init() {
  for (BrowserList::const_iterator i = BrowserList::begin();
       i != BrowserList::end(); ++i) {
    if (!(*i)->profile()->IsOffTheRecord())
      TrackBrowser(*i);
  }
}

void TabFinder::DidNavigateAnyFramePostCommit(
    TabContents* source,
    const content::LoadCommittedDetails& details,
    const ViewHostMsg_FrameNavigate_Params& params) {
  CancelRequestsFor(source);

  if (PageTransition::IsRedirect(params.transition)) {
    // If this is a redirect, we need to go to the db to get the start.
    FetchRedirectStart(source);
  } else if (params.redirects.size() > 1 ||
             params.redirects[0] != details.entry->url()) {
    tab_contents_to_url_[source] = params.redirects[0];
  }
}

bool TabFinder::TabMatchesURL(TabContents* tab_contents, const GURL& url) {
  if (tab_contents->GetURL() == url)
    return true;

  TabContentsToURLMap::const_iterator i =
      tab_contents_to_url_.find(tab_contents);
  return i != tab_contents_to_url_.end() && i->second == url;
}

TabContents* TabFinder::FindTabInBrowser(Browser* browser, const GURL& url) {
  if (!browser->is_type_tabbed())
    return NULL;

  for (int i = 0; i < browser->tab_count(); ++i) {
    if (TabMatchesURL(browser->GetTabContentsAt(i), url))
      return browser->GetTabContentsAt(i);
  }
  return NULL;
}

void TabFinder::TrackTab(TabContents* tab) {
  for (TabContentsObservers::const_iterator i = tab_contents_observers_.begin();
       i != tab_contents_observers_.end(); ++i) {
    if ((*i)->tab_contents() == tab) {
      // Already tracking the tab.
      return;
    }
  }
  TabContentsObserverImpl* observer = new TabContentsObserverImpl(tab, this);
  tab_contents_observers_.insert(observer);
  FetchRedirectStart(tab);
}

void TabFinder::TrackBrowser(Browser* browser) {
  for (int i = 0; i < browser->tab_count(); ++i)
    FetchRedirectStart(browser->GetTabContentsAt(i));
}

void TabFinder::TabDestroyed(TabContentsObserverImpl* observer) {
  DCHECK_GT(tab_contents_observers_.count(observer), 0u);
  tab_contents_observers_.erase(observer);
}

void TabFinder::CancelRequestsFor(TabContents* tab_contents) {
  if (tab_contents->profile()->IsOffTheRecord())
    return;

  tab_contents_to_url_.erase(tab_contents);

  HistoryService* history = tab_contents->profile()->GetHistoryService(
      Profile::EXPLICIT_ACCESS);
  if (history) {
    CancelableRequestProvider::Handle request_handle;
    if (callback_consumer_.GetFirstHandleForClientData(tab_contents,
                                                       &request_handle)) {
      history->CancelRequest(request_handle);
    }
  }
}

void TabFinder::FetchRedirectStart(TabContents* tab) {
  if (tab->profile()->IsOffTheRecord())
    return;

  NavigationEntry* committed_entry = tab->controller().GetLastCommittedEntry();
  if (!committed_entry || committed_entry->url().is_empty())
    return;

  HistoryService* history =tab->profile()->GetHistoryService(
      Profile::EXPLICIT_ACCESS);
  if (history) {
    CancelableRequestProvider::Handle request_handle =
        history->QueryRedirectsTo(
            committed_entry->url(),
            &callback_consumer_,
            NewCallback(this, &TabFinder::QueryRedirectsToComplete));
    callback_consumer_.SetClientData(history, request_handle, tab);
  }
}

void TabFinder::QueryRedirectsToComplete(HistoryService::Handle handle,
                                         GURL url,
                                         bool success,
                                         history::RedirectList* redirects) {
  if (success && !redirects->empty()) {
    TabContents* tab_contents =
        callback_consumer_.GetClientDataForCurrentRequest();
    DCHECK(tab_contents);
    tab_contents_to_url_[tab_contents] = redirects->back();
  }
}
<|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 QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qmath.h>

#include "qtextureglyphcache_p.h"

#include "private/qnumeric_p.h"
#include "private/qnativeimage_p.h"
#include "private/qfontengine_ft_p.h"

QT_BEGIN_NAMESPACE

// #define CACHE_DEBUG

void QTextureGlyphCache::populate(const QTextItemInt &ti,
                                  const QVarLengthArray<glyph_t> &glyphs,
                                  const QVarLengthArray<QFixedPoint> &)
{
#ifdef CACHE_DEBUG
    printf("Populating with '%s'\n", QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());
    qDebug() << " -> current transformation: " << m_transform;
#endif

    m_current_textitem = &ti;
    const int margin = glyphMargin();

    QHash<glyph_t, Coord> listItemCoordinates;
    int rowHeight = 0;

    // check each glyph for its metrics and get the required rowHeight.
    for (int i=0; i < glyphs.size(); ++i) {
        const glyph_t glyph = glyphs[i];
        if (coords.contains(glyph))
            continue;
        if (listItemCoordinates.contains(glyph))
            continue;
        glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyph, m_transform);

#ifdef CACHE_DEBUG
        printf("'%c' (%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f, ti.ascent=%.2f, ti.descent=%.2f\n",
               ti.chars[i].toLatin1(),
               glyph,
               metrics.width.toReal(),
               metrics.height.toReal(),
               metrics.xoff.toReal(),
               metrics.yoff.toReal(),
               metrics.x.toReal(),
               metrics.y.toReal(),
               ti.ascent.toReal(),
               ti.descent.toReal());
#endif
        int glyph_width = metrics.width.ceil().toInt();
        int glyph_height = metrics.height.ceil().toInt();
        if (glyph_height == 0 || glyph_width == 0)
            continue;
        glyph_width += margin * 2 + 4;
        glyph_height += margin * 2 + 4;
        // align to 8-bit boundary
        if (m_type == QFontEngineGlyphCache::Raster_Mono)
            glyph_width = (glyph_width+7)&~7;

        Coord c = { 0, 0, // will be filled in later
                    glyph_width,
                    glyph_height, // texture coords
                    metrics.x.round().truncate(),
                    -metrics.y.truncate() }; // baseline for horizontal scripts

        listItemCoordinates.insert(glyph, c);
        rowHeight = qMax(rowHeight, glyph_height);
    }
    if (listItemCoordinates.isEmpty())
        return;

    rowHeight += margin * 2;
    if (isNull())
        createCache(256, rowHeight);

    // now actually use the coords and paint the wanted glyps into cache.
    QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin();
    while (iter != listItemCoordinates.end()) {
        Coord c = iter.value();

        if (m_cx + c.w > m_w) {
            // no room on the current line, start new glyph strip
            m_cx = 0;
            m_cy = m_h;
        }
        if (m_cy + c.h > m_h) {
            int new_height;
            if (m_cx == 0) { // add a whole row
                new_height = m_h + rowHeight;
                m_cy = m_h;
            } else { // just extend row
                new_height = m_cy + rowHeight;
            }
            // if no room in the current texture - realloc a larger texture
            resizeTextureData(m_w, new_height);
            m_h = new_height;
        }

        c.x = m_cx;
        c.y = m_cy;

        fillTexture(c, iter.key());
        coords.insert(iter.key(), c);

        if (m_cx + c.w > m_w) {
            m_cx = 0;
            m_cy += rowHeight;
        } else {
            // for the Mono case, glyph_width is 8-bit aligned,
            // and therefore so will m_cx
            m_cx += c.w;
        }
        ++iter;
    }

}

QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
{
#if defined(Q_WS_X11)
    if (m_transform.type() > QTransform::TxTranslate) {
        QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
        QImage::Format imageFormat = QImage::Format_Invalid;
        switch (m_type) {
        case Raster_RGBMask:
            format = QFontEngineFT::Format_A32;
            imageFormat = QImage::Format_RGB32;
            break;
        case Raster_A8:
            format = QFontEngineFT::Format_A8;
            imageFormat = QImage::Format_Indexed8;
            break;
        case Raster_Mono:
            format = QFontEngineFT::Format_Mono;
            imageFormat = QImage::Format_Mono;
            break;
        };

        QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_textitem->fontEngine);
        QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform);

        if (gset && ft->loadGlyphs(gset, &g, 1, format)) {
            QFontEngineFT::Glyph *glyph = gset->glyph_data.value(g);
            const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3
                               : (glyph->width + 3) & ~3);
            return QImage(glyph->data, glyph->width, glyph->height, bytesPerLine, imageFormat);
        }
    } else
#endif
    if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
        return m_current_textitem->fontEngine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
    else
        return m_current_textitem->fontEngine->alphaMapForGlyph(g, m_transform);

    return QImage();
}

/************************************************************************
 * QImageTextureGlyphCache
 */

void QImageTextureGlyphCache::resizeTextureData(int width, int height)
{
    m_image = m_image.copy(0, 0, width, height);
}

void QImageTextureGlyphCache::createTextureData(int width, int height)
{
    switch (m_type) {
    case QFontEngineGlyphCache::Raster_Mono:
        m_image = QImage(width, height, QImage::Format_Mono);
        break;
    case QFontEngineGlyphCache::Raster_A8: {
        m_image = QImage(width, height, QImage::Format_Indexed8);
        m_image.fill(0);
        QVector<QRgb> colors(256);
        QRgb *it = colors.data();
        for (int i=0; i<256; ++i, ++it)
            *it = 0xff000000 | i | (i<<8) | (i<<16);
        m_image.setColorTable(colors);
        break;   }
    case QFontEngineGlyphCache::Raster_RGBMask:
        m_image = QImage(width, height, QImage::Format_RGB32);
        break;
    }
}

int QImageTextureGlyphCache::glyphMargin() const
{
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
    return 0;
#else
    return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
#endif
}

void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g)
{
    QImage mask = textureMapForGlyph(g);

#ifdef CACHE_DEBUG
    printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
    if (mask.width() > c.w || mask.height() > c.h) {
        printf("   ERROR; mask is bigger than reserved space! %dx%d instead of %dx%d\n", mask.width(), mask.height(), c.w,c.h);
        return;
    }
#endif

    if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
        QPainter p(&m_image);
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.fillRect(c.x, c.y, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this
        p.drawImage(c.x, c.y, mask);
        p.end();
    } else if (m_type == QFontEngineGlyphCache::Raster_Mono) {
        if (mask.depth() > 1) {
            // TODO optimize this
            mask = mask.alphaChannel();
            mask.invertPixels();
            mask = mask.convertToFormat(QImage::Format_Mono);
        }

        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        for (int y = 0; y < c.h; ++y) {
            uchar *dest = d + (c.y + y) *dbpl + c.x/8;

            if (y < mh) {
                uchar *src = mask.scanLine(y);
                for (int x = 0; x < c.w/8; ++x) {
                    if (x < (mw+7)/8)
                        dest[x] = src[x];
                    else
                        dest[x] = 0;
                }
            } else {
                for (int x = 0; x < c.w/8; ++x)
                    dest[x] = 0;
            }
        }
    } else { // A8
        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        if (mask.depth() == 1) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    uchar *src = (uchar *) mask.scanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0;
                    }
                }
            }
        } else if (mask.depth() == 8) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    uchar *src = (uchar *) mask.scanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = src[x];
                    }
                }
            }
        }
    }

#ifdef CACHE_DEBUG
//     QPainter p(&m_image);
//     p.drawLine(
    QPoint base(c.x + glyphMargin(), c.y + glyphMargin() + c.baseLineY-1);
    if (m_image.rect().contains(base))
        m_image.setPixel(base, 255);
    m_image.save(QString::fromLatin1("cache-%1-%2-%3.png")
                 .arg(m_current_textitem->font().family())
                 .arg(m_current_textitem->font().pointSize())
                 .arg(m_transform.type()));
#endif
}

QT_END_NAMESPACE
<commit_msg>Add texture glyph width cache default.<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 QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qmath.h>

#include "qtextureglyphcache_p.h"

#include "private/qnumeric_p.h"
#include "private/qnativeimage_p.h"
#include "private/qfontengine_ft_p.h"

#ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH
#define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 256
#endif

QT_BEGIN_NAMESPACE

// #define CACHE_DEBUG

void QTextureGlyphCache::populate(const QTextItemInt &ti,
                                  const QVarLengthArray<glyph_t> &glyphs,
                                  const QVarLengthArray<QFixedPoint> &)
{
#ifdef CACHE_DEBUG
    printf("Populating with '%s'\n", QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());
    qDebug() << " -> current transformation: " << m_transform;
#endif

    m_current_textitem = &ti;
    const int margin = glyphMargin();

    QHash<glyph_t, Coord> listItemCoordinates;
    int rowHeight = 0;

    // check each glyph for its metrics and get the required rowHeight.
    for (int i=0; i < glyphs.size(); ++i) {
        const glyph_t glyph = glyphs[i];
        if (coords.contains(glyph))
            continue;
        if (listItemCoordinates.contains(glyph))
            continue;
        glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyph, m_transform);

#ifdef CACHE_DEBUG
        printf("'%c' (%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f, ti.ascent=%.2f, ti.descent=%.2f\n",
               ti.chars[i].toLatin1(),
               glyph,
               metrics.width.toReal(),
               metrics.height.toReal(),
               metrics.xoff.toReal(),
               metrics.yoff.toReal(),
               metrics.x.toReal(),
               metrics.y.toReal(),
               ti.ascent.toReal(),
               ti.descent.toReal());
#endif
        int glyph_width = metrics.width.ceil().toInt();
        int glyph_height = metrics.height.ceil().toInt();
        if (glyph_height == 0 || glyph_width == 0)
            continue;
        glyph_width += margin * 2 + 4;
        glyph_height += margin * 2 + 4;
        // align to 8-bit boundary
        if (m_type == QFontEngineGlyphCache::Raster_Mono)
            glyph_width = (glyph_width+7)&~7;

        Coord c = { 0, 0, // will be filled in later
                    glyph_width,
                    glyph_height, // texture coords
                    metrics.x.round().truncate(),
                    -metrics.y.truncate() }; // baseline for horizontal scripts

        listItemCoordinates.insert(glyph, c);
        rowHeight = qMax(rowHeight, glyph_height);
    }
    if (listItemCoordinates.isEmpty())
        return;

    rowHeight += margin * 2;
    if (isNull())
        createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight);

    // now actually use the coords and paint the wanted glyps into cache.
    QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin();
    while (iter != listItemCoordinates.end()) {
        Coord c = iter.value();

        if (m_cx + c.w > m_w) {
            // no room on the current line, start new glyph strip
            m_cx = 0;
            m_cy = m_h;
        }
        if (m_cy + c.h > m_h) {
            int new_height;
            if (m_cx == 0) { // add a whole row
                new_height = m_h + rowHeight;
                m_cy = m_h;
            } else { // just extend row
                new_height = m_cy + rowHeight;
            }
            // if no room in the current texture - realloc a larger texture
            resizeTextureData(m_w, new_height);
            m_h = new_height;
        }

        c.x = m_cx;
        c.y = m_cy;

        fillTexture(c, iter.key());
        coords.insert(iter.key(), c);

        if (m_cx + c.w > m_w) {
            m_cx = 0;
            m_cy += rowHeight;
        } else {
            // for the Mono case, glyph_width is 8-bit aligned,
            // and therefore so will m_cx
            m_cx += c.w;
        }
        ++iter;
    }

}

QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const
{
#if defined(Q_WS_X11)
    if (m_transform.type() > QTransform::TxTranslate) {
        QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
        QImage::Format imageFormat = QImage::Format_Invalid;
        switch (m_type) {
        case Raster_RGBMask:
            format = QFontEngineFT::Format_A32;
            imageFormat = QImage::Format_RGB32;
            break;
        case Raster_A8:
            format = QFontEngineFT::Format_A8;
            imageFormat = QImage::Format_Indexed8;
            break;
        case Raster_Mono:
            format = QFontEngineFT::Format_Mono;
            imageFormat = QImage::Format_Mono;
            break;
        };

        QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_textitem->fontEngine);
        QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform);

        if (gset && ft->loadGlyphs(gset, &g, 1, format)) {
            QFontEngineFT::Glyph *glyph = gset->glyph_data.value(g);
            const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3
                               : (glyph->width + 3) & ~3);
            return QImage(glyph->data, glyph->width, glyph->height, bytesPerLine, imageFormat);
        }
    } else
#endif
    if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
        return m_current_textitem->fontEngine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
    else
        return m_current_textitem->fontEngine->alphaMapForGlyph(g, m_transform);

    return QImage();
}

/************************************************************************
 * QImageTextureGlyphCache
 */

void QImageTextureGlyphCache::resizeTextureData(int width, int height)
{
    m_image = m_image.copy(0, 0, width, height);
}

void QImageTextureGlyphCache::createTextureData(int width, int height)
{
    switch (m_type) {
    case QFontEngineGlyphCache::Raster_Mono:
        m_image = QImage(width, height, QImage::Format_Mono);
        break;
    case QFontEngineGlyphCache::Raster_A8: {
        m_image = QImage(width, height, QImage::Format_Indexed8);
        m_image.fill(0);
        QVector<QRgb> colors(256);
        QRgb *it = colors.data();
        for (int i=0; i<256; ++i, ++it)
            *it = 0xff000000 | i | (i<<8) | (i<<16);
        m_image.setColorTable(colors);
        break;   }
    case QFontEngineGlyphCache::Raster_RGBMask:
        m_image = QImage(width, height, QImage::Format_RGB32);
        break;
    }
}

int QImageTextureGlyphCache::glyphMargin() const
{
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
    return 0;
#else
    return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
#endif
}

void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g)
{
    QImage mask = textureMapForGlyph(g);

#ifdef CACHE_DEBUG
    printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
    if (mask.width() > c.w || mask.height() > c.h) {
        printf("   ERROR; mask is bigger than reserved space! %dx%d instead of %dx%d\n", mask.width(), mask.height(), c.w,c.h);
        return;
    }
#endif

    if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
        QPainter p(&m_image);
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.fillRect(c.x, c.y, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this
        p.drawImage(c.x, c.y, mask);
        p.end();
    } else if (m_type == QFontEngineGlyphCache::Raster_Mono) {
        if (mask.depth() > 1) {
            // TODO optimize this
            mask = mask.alphaChannel();
            mask.invertPixels();
            mask = mask.convertToFormat(QImage::Format_Mono);
        }

        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        for (int y = 0; y < c.h; ++y) {
            uchar *dest = d + (c.y + y) *dbpl + c.x/8;

            if (y < mh) {
                uchar *src = mask.scanLine(y);
                for (int x = 0; x < c.w/8; ++x) {
                    if (x < (mw+7)/8)
                        dest[x] = src[x];
                    else
                        dest[x] = 0;
                }
            } else {
                for (int x = 0; x < c.w/8; ++x)
                    dest[x] = 0;
            }
        }
    } else { // A8
        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        if (mask.depth() == 1) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    uchar *src = (uchar *) mask.scanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0;
                    }
                }
            }
        } else if (mask.depth() == 8) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    uchar *src = (uchar *) mask.scanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = src[x];
                    }
                }
            }
        }
    }

#ifdef CACHE_DEBUG
//     QPainter p(&m_image);
//     p.drawLine(
    QPoint base(c.x + glyphMargin(), c.y + glyphMargin() + c.baseLineY-1);
    if (m_image.rect().contains(base))
        m_image.setPixel(base, 255);
    m_image.save(QString::fromLatin1("cache-%1-%2-%3.png")
                 .arg(m_current_textitem->font().family())
                 .arg(m_current_textitem->font().pointSize())
                 .arg(m_transform.type()));
#endif
}

QT_END_NAMESPACE
<|endoftext|>


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

#include "chrome/test/webdriver/dispatch.h"

#include <sstream>
#include <string>
#include <vector>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chrome/test/webdriver/http_response.h"
#include "chrome/test/webdriver/commands/command.h"
#include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/utility_functions.h"

namespace webdriver {

namespace {

bool ForbidsMessageBody(const std::string& request_method,
                        const HttpResponse& response) {
  return request_method == "HEAD" ||
         response.status() == HttpResponse::kNoContent ||
         response.status() == HttpResponse::kNotModified ||
         (response.status() >= 100 && response.status() < 200);
}

void DispatchCommand(Command* const command,
                     const std::string& method,
                     Response* response) {
  if (!command->Init(response))
    return;

  if (method == "POST") {
    command->ExecutePost(response);
  } else if (method == "GET") {
    command->ExecuteGet(response);
  } else if (method == "DELETE") {
    command->ExecuteDelete(response);
  } else {
    NOTREACHED();
  }
}

void Shutdown(struct mg_connection* connection,
              const struct mg_request_info* request_info,
              void* user_data) {
  base::WaitableEvent* shutdown_event =
      reinterpret_cast<base::WaitableEvent*>(user_data);
  mg_printf(connection, "HTTP/1.1 200 OK\r\n\r\n");
  shutdown_event->Signal();
}

void SendNotImplementedError(struct mg_connection* connection,
                             const struct mg_request_info* request_info,
                             void* user_data) {
  // Send a well-formed WebDriver JSON error response to ensure clients
  // handle it correctly.
  std::string body = base::StringPrintf(
      "{\"status\":%d,\"value\":{\"message\":"
      "\"Command has not been implemented yet: %s %s\"}}",
      kUnknownCommand, request_info->request_method, request_info->uri);

  std::string header = base::StringPrintf(
      "HTTP/1.1 501 Not Implemented\r\n"
      "Content-Type:application/json\r\n"
      "Content-Length:%" PRIuS "\r\n"
      "\r\n", body.length());

  LOG(ERROR) << header << body;
  mg_write(connection, header.data(), header.length());
  mg_write(connection, body.data(), body.length());
}

}  // namespace

namespace internal {

void PrepareHttpResponse(const Response& command_response,
                         HttpResponse* const http_response) {
  ErrorCode status = command_response.GetStatus();
  switch (status) {
    case kSuccess:
      http_response->set_status(HttpResponse::kOk);
      break;

    // TODO(jleyba): kSeeOther, kBadRequest, kSessionNotFound,
    // and kMethodNotAllowed should be detected before creating
    // a command_response, and should thus not need conversion.
    case kSeeOther: {
      const Value* const value = command_response.GetValue();
      std::string location;
      if (!value->GetAsString(&location)) {
        // This should never happen.
        http_response->set_status(HttpResponse::kInternalServerError);
        http_response->SetBody("Unable to set 'Location' header: response "
                               "value is not a string: " +
                               command_response.ToJSON());
        return;
      }
      http_response->AddHeader("Location", location);
      http_response->set_status(HttpResponse::kSeeOther);
      break;
    }

    case kBadRequest:
    case kSessionNotFound:
      http_response->set_status(status);
      break;

    case kMethodNotAllowed: {
      const Value* const value = command_response.GetValue();
      if (!value->IsType(Value::TYPE_LIST)) {
        // This should never happen.
        http_response->set_status(HttpResponse::kInternalServerError);
        http_response->SetBody(
            "Unable to set 'Allow' header: response value was "
            "not a list of strings: " + command_response.ToJSON());
        return;
      }

      const ListValue* const list_value =
          static_cast<const ListValue* const>(value);
      std::vector<std::string> allowed_methods;
      for (size_t i = 0; i < list_value->GetSize(); ++i) {
        std::string method;
        if (list_value->GetString(i, &method)) {
          allowed_methods.push_back(method);
        } else {
          // This should never happen.
          http_response->set_status(HttpResponse::kInternalServerError);
          http_response->SetBody(
              "Unable to set 'Allow' header: response value was "
              "not a list of strings: " + command_response.ToJSON());
          return;
        }
      }
      http_response->AddHeader("Allow", JoinString(allowed_methods, ','));
      http_response->set_status(HttpResponse::kMethodNotAllowed);
      break;
    }

    // All other errors should be treated as generic 500s. The client
    // will be responsible for inspecting the message body for details.
    case kInternalServerError:
    default:
      http_response->set_status(HttpResponse::kInternalServerError);
      break;
  }

  http_response->SetMimeType("application/json; charset=utf-8");
  http_response->SetBody(command_response.ToJSON());
}

void SendResponse(struct mg_connection* const connection,
                  const std::string& request_method,
                  const Response& response) {
  HttpResponse http_response;
  PrepareHttpResponse(response, &http_response);

  std::string message_header = base::StringPrintf("HTTP/1.1 %d %s\r\n",
      http_response.status(), http_response.GetReasonPhrase().c_str());

  typedef HttpResponse::HeaderMap::const_iterator HeaderIter;
  for (HeaderIter header = http_response.headers()->begin();
       header != http_response.headers()->end();
       ++header) {
    message_header.append(base::StringPrintf("%s:%s\r\n",
        header->first.c_str(), header->second.c_str()));
  }
  message_header.append("\r\n");

  mg_write(connection, message_header.data(), message_header.length());
  if (!ForbidsMessageBody(request_method, http_response))
    mg_write(connection, http_response.data(), http_response.length());
}

bool ParseRequestInfo(const struct mg_request_info* const request_info,
                      std::string* method,
                      std::vector<std::string>* path_segments,
                      DictionaryValue** parameters,
                      Response* const response) {
  *method = request_info->request_method;
  if (*method == "HEAD")
    *method = "GET";
  else if (*method == "PUT")
    *method = "POST";

  std::string uri(request_info->uri);
  SessionManager* manager = SessionManager::GetInstance();
  uri = uri.substr(manager->url_base().length());

  base::SplitString(uri, '/', path_segments);

  if (*method == "POST" && request_info->post_data_len > 0) {
    VLOG(1) << "...parsing request body";
    std::string json(request_info->post_data, request_info->post_data_len);
    std::string error;
    if (!ParseJSONDictionary(json, parameters, &error)) {
      SET_WEBDRIVER_ERROR(response,
          "Failed to parse command data: " + error + "\n  Data: " + json,
          kBadRequest);
      return false;
    }
  }
  VLOG(1) << "Parsed " << method << " " << uri
        << std::string(request_info->post_data, request_info->post_data_len);
  return true;
}

void DispatchHelper(Command* command_ptr,
                    const std::string& method,
                    Response* response) {
  CHECK(method == "GET" || method == "POST" || method == "DELETE");
  scoped_ptr<Command> command(command_ptr);

  if ((method == "GET" && !command->DoesGet()) ||
      (method == "POST" && !command->DoesPost()) ||
      (method == "DELETE" && !command->DoesDelete())) {
    ListValue* methods = new ListValue;
    if (command->DoesPost())
      methods->Append(Value::CreateStringValue("POST"));
    if (command->DoesGet()) {
      methods->Append(Value::CreateStringValue("GET"));
      methods->Append(Value::CreateStringValue("HEAD"));
    }
    if (command->DoesDelete())
      methods->Append(Value::CreateStringValue("DELETE"));
    response->SetStatus(kMethodNotAllowed);
    response->SetValue(methods);
    return;
  }

  DispatchCommand(command.get(), method, response);
}

}  // namespace internal

Dispatcher::Dispatcher(struct mg_context* context, const std::string& root)
    : context_(context), root_(root) {}

Dispatcher::~Dispatcher() {}

void Dispatcher::AddShutdown(const std::string& pattern,
                             base::WaitableEvent* shutdown_event) {
  mg_set_uri_callback(context_, (root_ + pattern).c_str(), &Shutdown, NULL);
}

void Dispatcher::SetNotImplemented(const std::string& pattern) {
  mg_set_uri_callback(context_, (root_ + pattern).c_str(),
                      &SendNotImplementedError, NULL);
}

}  // namespace webdriver
<commit_msg>Fix ChromeDriver shutdown due to regression in 76517. BUG=none TEST=none Review URL: http://codereview.chromium.org/6610004<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/webdriver/dispatch.h"

#include <sstream>
#include <string>
#include <vector>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chrome/test/webdriver/http_response.h"
#include "chrome/test/webdriver/commands/command.h"
#include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/utility_functions.h"

namespace webdriver {

namespace {

bool ForbidsMessageBody(const std::string& request_method,
                        const HttpResponse& response) {
  return request_method == "HEAD" ||
         response.status() == HttpResponse::kNoContent ||
         response.status() == HttpResponse::kNotModified ||
         (response.status() >= 100 && response.status() < 200);
}

void DispatchCommand(Command* const command,
                     const std::string& method,
                     Response* response) {
  if (!command->Init(response))
    return;

  if (method == "POST") {
    command->ExecutePost(response);
  } else if (method == "GET") {
    command->ExecuteGet(response);
  } else if (method == "DELETE") {
    command->ExecuteDelete(response);
  } else {
    NOTREACHED();
  }
}

void Shutdown(struct mg_connection* connection,
              const struct mg_request_info* request_info,
              void* user_data) {
  base::WaitableEvent* shutdown_event =
      reinterpret_cast<base::WaitableEvent*>(user_data);
  mg_printf(connection, "HTTP/1.1 200 OK\r\n\r\n");
  shutdown_event->Signal();
}

void SendNotImplementedError(struct mg_connection* connection,
                             const struct mg_request_info* request_info,
                             void* user_data) {
  // Send a well-formed WebDriver JSON error response to ensure clients
  // handle it correctly.
  std::string body = base::StringPrintf(
      "{\"status\":%d,\"value\":{\"message\":"
      "\"Command has not been implemented yet: %s %s\"}}",
      kUnknownCommand, request_info->request_method, request_info->uri);

  std::string header = base::StringPrintf(
      "HTTP/1.1 501 Not Implemented\r\n"
      "Content-Type:application/json\r\n"
      "Content-Length:%" PRIuS "\r\n"
      "\r\n", body.length());

  LOG(ERROR) << header << body;
  mg_write(connection, header.data(), header.length());
  mg_write(connection, body.data(), body.length());
}

}  // namespace

namespace internal {

void PrepareHttpResponse(const Response& command_response,
                         HttpResponse* const http_response) {
  ErrorCode status = command_response.GetStatus();
  switch (status) {
    case kSuccess:
      http_response->set_status(HttpResponse::kOk);
      break;

    // TODO(jleyba): kSeeOther, kBadRequest, kSessionNotFound,
    // and kMethodNotAllowed should be detected before creating
    // a command_response, and should thus not need conversion.
    case kSeeOther: {
      const Value* const value = command_response.GetValue();
      std::string location;
      if (!value->GetAsString(&location)) {
        // This should never happen.
        http_response->set_status(HttpResponse::kInternalServerError);
        http_response->SetBody("Unable to set 'Location' header: response "
                               "value is not a string: " +
                               command_response.ToJSON());
        return;
      }
      http_response->AddHeader("Location", location);
      http_response->set_status(HttpResponse::kSeeOther);
      break;
    }

    case kBadRequest:
    case kSessionNotFound:
      http_response->set_status(status);
      break;

    case kMethodNotAllowed: {
      const Value* const value = command_response.GetValue();
      if (!value->IsType(Value::TYPE_LIST)) {
        // This should never happen.
        http_response->set_status(HttpResponse::kInternalServerError);
        http_response->SetBody(
            "Unable to set 'Allow' header: response value was "
            "not a list of strings: " + command_response.ToJSON());
        return;
      }

      const ListValue* const list_value =
          static_cast<const ListValue* const>(value);
      std::vector<std::string> allowed_methods;
      for (size_t i = 0; i < list_value->GetSize(); ++i) {
        std::string method;
        if (list_value->GetString(i, &method)) {
          allowed_methods.push_back(method);
        } else {
          // This should never happen.
          http_response->set_status(HttpResponse::kInternalServerError);
          http_response->SetBody(
              "Unable to set 'Allow' header: response value was "
              "not a list of strings: " + command_response.ToJSON());
          return;
        }
      }
      http_response->AddHeader("Allow", JoinString(allowed_methods, ','));
      http_response->set_status(HttpResponse::kMethodNotAllowed);
      break;
    }

    // All other errors should be treated as generic 500s. The client
    // will be responsible for inspecting the message body for details.
    case kInternalServerError:
    default:
      http_response->set_status(HttpResponse::kInternalServerError);
      break;
  }

  http_response->SetMimeType("application/json; charset=utf-8");
  http_response->SetBody(command_response.ToJSON());
}

void SendResponse(struct mg_connection* const connection,
                  const std::string& request_method,
                  const Response& response) {
  HttpResponse http_response;
  PrepareHttpResponse(response, &http_response);

  std::string message_header = base::StringPrintf("HTTP/1.1 %d %s\r\n",
      http_response.status(), http_response.GetReasonPhrase().c_str());

  typedef HttpResponse::HeaderMap::const_iterator HeaderIter;
  for (HeaderIter header = http_response.headers()->begin();
       header != http_response.headers()->end();
       ++header) {
    message_header.append(base::StringPrintf("%s:%s\r\n",
        header->first.c_str(), header->second.c_str()));
  }
  message_header.append("\r\n");

  mg_write(connection, message_header.data(), message_header.length());
  if (!ForbidsMessageBody(request_method, http_response))
    mg_write(connection, http_response.data(), http_response.length());
}

bool ParseRequestInfo(const struct mg_request_info* const request_info,
                      std::string* method,
                      std::vector<std::string>* path_segments,
                      DictionaryValue** parameters,
                      Response* const response) {
  *method = request_info->request_method;
  if (*method == "HEAD")
    *method = "GET";
  else if (*method == "PUT")
    *method = "POST";

  std::string uri(request_info->uri);
  SessionManager* manager = SessionManager::GetInstance();
  uri = uri.substr(manager->url_base().length());

  base::SplitString(uri, '/', path_segments);

  if (*method == "POST" && request_info->post_data_len > 0) {
    VLOG(1) << "...parsing request body";
    std::string json(request_info->post_data, request_info->post_data_len);
    std::string error;
    if (!ParseJSONDictionary(json, parameters, &error)) {
      SET_WEBDRIVER_ERROR(response,
          "Failed to parse command data: " + error + "\n  Data: " + json,
          kBadRequest);
      return false;
    }
  }
  VLOG(1) << "Parsed " << method << " " << uri
        << std::string(request_info->post_data, request_info->post_data_len);
  return true;
}

void DispatchHelper(Command* command_ptr,
                    const std::string& method,
                    Response* response) {
  CHECK(method == "GET" || method == "POST" || method == "DELETE");
  scoped_ptr<Command> command(command_ptr);

  if ((method == "GET" && !command->DoesGet()) ||
      (method == "POST" && !command->DoesPost()) ||
      (method == "DELETE" && !command->DoesDelete())) {
    ListValue* methods = new ListValue;
    if (command->DoesPost())
      methods->Append(Value::CreateStringValue("POST"));
    if (command->DoesGet()) {
      methods->Append(Value::CreateStringValue("GET"));
      methods->Append(Value::CreateStringValue("HEAD"));
    }
    if (command->DoesDelete())
      methods->Append(Value::CreateStringValue("DELETE"));
    response->SetStatus(kMethodNotAllowed);
    response->SetValue(methods);
    return;
  }

  DispatchCommand(command.get(), method, response);
}

}  // namespace internal

Dispatcher::Dispatcher(struct mg_context* context, const std::string& root)
    : context_(context), root_(root) {}

Dispatcher::~Dispatcher() {}

void Dispatcher::AddShutdown(const std::string& pattern,
                             base::WaitableEvent* shutdown_event) {
  mg_set_uri_callback(context_, (root_ + pattern).c_str(), &Shutdown,
                      shutdown_event);
}

void Dispatcher::SetNotImplemented(const std::string& pattern) {
  mg_set_uri_callback(context_, (root_ + pattern).c_str(),
                      &SendNotImplementedError, NULL);
}

}  // namespace webdriver
<|endoftext|>


<commit_before>#include <map>
#include <string>
#include <iostream>

#include <docopt/docopt.h>

#include "serve.hpp"
#include "simple_commands.hpp"

int main(int argc, char * argv[])
{
    static const char usage[] =
R"(Remote SimGrid command-line tool.

Usage:
  rsg serve <platform-file> [--port=<port>] [-- <sg-options>...]
  rsg add-actor <actor-name> <sg-host> [options] [--] <command> [<command-args>...]
  rsg start [options]
  rsg status [options]
  rsg kill [options]
  rsg --help

Options:
  -h --hostname <host>  Server's hostname [default: 127.0.0.1].
  -p --port <port>      Server's TCP port [default: 35000].
)";

    // Parse CLI arguments.
    auto args = docopt::docopt(usage, { argv + 1, argv + argc }, true);

    // Check argument validity
    std::string server_hostname = args["--hostname"].asString();
    int server_port = args["--port"].asLong();

    // Debug printing, should be removed.
    /*std::cout << "Arguments:" << std::endl;
    for(auto const & arg : args) {
        std::cout << "  " << arg.first << ": " << arg.second << std::endl;
    }*/

    // Manage subcommands.
    if (args["serve"].asBool())
    {
        std::string platform_file = args["<platform-file>"].asString();
        std::vector<std::string> simgrid_options = args["<sg-options>"].asStringList();
        serve(platform_file, server_port, simgrid_options);
    }
    else if (args["kill"].asBool())
    {
        kill(server_hostname, server_port);
    }
    else if (args["start"].asBool())
    {
        start(server_hostname, server_port);
    }
    else if (args["status"].asBool())
    {
        status(server_hostname, server_port);
    }
    else if (args["add-actor"].asBool())
    {
        std::string actor_name = args["<actor-name>"].asString();
        std::string vhost_name = args["<sg-host>"].asString();
        add_actor(server_hostname, server_port, actor_name, vhost_name);
    }

    return 0;
}
<commit_msg>[code] docopt: explicit arguments<commit_after>#include <map>
#include <string>
#include <iostream>

#include <docopt/docopt.h>

#include "serve.hpp"
#include "simple_commands.hpp"

int main(int argc, char * argv[])
{
    static const char usage[] =
R"(Remote SimGrid command-line tool.

Usage:
  rsg serve <platform-file> [--port=<port>] [-- <sg-options>...]
  rsg add-actor <actor-name> <sg-host> [--hostname=<host>] [--port=<port>]
                [--] <command> [<command-args>...]
  rsg start [--hostname=<host>] [--port=<port>]
  rsg status [--hostname=<host>] [--port=<port>]
  rsg kill [--hostname=<host>] [--port=<port>]
  rsg --help

Options:
  -h --hostname <host>  Server's hostname [default: 127.0.0.1].
  -p --port <port>      Server's TCP port [default: 35000].
)";

    // Parse CLI arguments.
    auto args = docopt::docopt(usage, { argv + 1, argv + argc }, true);

    // Check argument validity
    std::string server_hostname = args["--hostname"].asString();
    int server_port = args["--port"].asLong();

    // Debug printing, should be removed.
    /*std::cout << "Arguments:" << std::endl;
    for(auto const & arg : args) {
        std::cout << "  " << arg.first << ": " << arg.second << std::endl;
    }*/

    // Manage subcommands.
    if (args["serve"].asBool())
    {
        std::string platform_file = args["<platform-file>"].asString();
        std::vector<std::string> simgrid_options = args["<sg-options>"].asStringList();
        serve(platform_file, server_port, simgrid_options);
    }
    else if (args["kill"].asBool())
    {
        kill(server_hostname, server_port);
    }
    else if (args["start"].asBool())
    {
        start(server_hostname, server_port);
    }
    else if (args["status"].asBool())
    {
        status(server_hostname, server_port);
    }
    else if (args["add-actor"].asBool())
    {
        std::string actor_name = args["<actor-name>"].asString();
        std::string vhost_name = args["<sg-host>"].asString();
        add_actor(server_hostname, server_port, actor_name, vhost_name);
    }

    return 0;
}
<|endoftext|>