<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/mdia/test/mdiatestmba.H $                        */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2020                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __TEST_MDIATESTMBA_H
#define __TEST_MDIATESTMBA_H

/**
 * @file mdiatestmba.H
 * @brief mdiamba unit tests
 */

#include <builtins.h>
#include <cxxtest/TestSuite.H>
#include <targeting/common/target.H>
#include <targeting/common/utilFilter.H>
#include "../mdiafwd.H"
#include "../mdiaglobals.H"
#include "../mdiasm.H"

class MdiaMbaTest : public CxxTest::TestSuite
{
    public:

        void testGetDiagnosticMode(void)
        {
            using namespace MDIA;
            using namespace TARGETING;

            TS_TRACE(ENTER_MRK "testGetDiagnosticMode");

            TargetHandleList mbaList;
            getAllChiplets(mbaList, TYPE_MBA);

            if( !mbaList.empty() )
            {
                DiagMode mode;
                Globals globals;
                TargetHandle_t mba = mbaList[0];

                errlHndl_t err = getDiagnosticMode(
                                        globals, mba, mode);

                if(err)
                {
                    TS_FAIL("getDiagnosticMode failed "
                            "unexpectedly");
                }

                if(mode != ONE_PATTERN)
                {
                    TS_FAIL("mode != ONE_PATTERN");
                }
            }

            TS_TRACE(EXIT_MRK "testGetDiagnosticMode");
        }

        void testGetWorkFlow(void)
        {
            using namespace MDIA;
            using namespace TARGETING;

            TS_TRACE(ENTER_MRK "testGetWorkFlow");

            Globals globals;
            TargetHandle_t mba = 0;
            DiagMode mode;
            errlHndl_t err = NULL;
            TargetHandleList mbaList;
            getAllChiplets(mbaList, TYPE_MBA);

            if( !mbaList.empty() )
            {
                mba = mbaList[0];
                err = getDiagnosticMode(
                                globals, mba, mode);

                if(err)
                {
                    TS_FAIL("getDiagnosticMode "
                            "failed unexpectedly");
                }

                if(mode != ONE_PATTERN)
                {
                    TS_FAIL("mode != ONE_PATTERN");
                }
            }

            WorkFlow wf, expected;

            expected.push_back(RESTORE_DRAM_REPAIRS);
            expected.push_back(START_PATTERN_0);
            expected.push_back(START_SCRUB);
            expected.push_back(CLEAR_HW_CHANGED_STATE);

            err = getWorkFlow(mode, wf, globals);

            if(err)
            {
                TS_FAIL("getWorkFlow failed unexpectedly");
            }

            if(wf.size() != expected.size())
            {
                TS_FAIL("incorrect workflow size for init only mode");
            }

            int64_t index = wf.size();

            while(index-- != 0)
            {
                if(wf[index] != expected[index])
                {
                    TS_FAIL("workflow entry incorrect or out of order");
                }
            }

            TS_TRACE(EXIT_MRK "testGetWorkFlow");
        }
};
#endif
<commit_msg>MDIA: Update mdiatestmba test cases<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/mdia/test/mdiatestmba.H $                        */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2020                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __TEST_MDIATESTMBA_H
#define __TEST_MDIATESTMBA_H

/**
 * @file mdiatestmba.H
 * @brief mdiamba unit tests
 */

#include <builtins.h>
#include <cxxtest/TestSuite.H>
#include <targeting/common/target.H>
#include <targeting/common/utilFilter.H>
#include "../mdiafwd.H"
#include "../mdiaglobals.H"
#include "../mdiasm.H"

class MdiaMbaTest : public CxxTest::TestSuite
{
    public:

        void testGetDiagnosticMode(void)
        {
            using namespace MDIA;
            using namespace TARGETING;

            TS_TRACE(ENTER_MRK "testGetDiagnosticMode");

            TargetHandleList list;
            fapi2::TargetType type = getMdiaTargetType();
            if ( fapi2::TARGET_TYPE_MBA_CHIPLET == type )
            {
                TARGETING::getAllChiplets( list, TYPE_MBA );
            }
            else if ( fapi2::TARGET_TYPE_MCBIST == type )
            {
                TARGETING::getAllChiplets( list, TYPE_MCBIST );
            }
            else if ( fapi2::TARGET_TYPE_OCMB_CHIP == type )
            {
                TARGETING::getAllChips( list, TYPE_OCMB_CHIP );
            }

            if( !mbaList.empty() )
            {
                DiagMode mode;
                Globals globals;
                globals.simicsRunning = true;
                TargetHandle_t trgt = list[0];

                errlHndl_t err = getDiagnosticMode(
                                        globals, mba, mode);

                if(err)
                {
                    TS_FAIL("getDiagnosticMode failed "
                            "unexpectedly");
                }

                if(mode != ONE_PATTERN)
                {
                    TS_FAIL("mode != ONE_PATTERN");
                }
            }

            TS_TRACE(EXIT_MRK "testGetDiagnosticMode");
        }

        void testGetWorkFlow(void)
        {
            using namespace MDIA;
            using namespace TARGETING;

            TS_TRACE(ENTER_MRK "testGetWorkFlow");

            Globals globals;
            globals.simicsRunning = true;
            TargetHandle_t trgt = 0;
            DiagMode mode;
            errlHndl_t err = NULL;
            TargetHandleList mbaList;
            getAllChiplets(mbaList, TYPE_MBA);

            TargetHandleList list;
            fapi2::TargetType type = getMdiaTargetType();
            if ( fapi2::TARGET_TYPE_MBA_CHIPLET == type )
            {
                TARGETING::getAllChiplets( list, TYPE_MBA );
            }
            else if ( fapi2::TARGET_TYPE_MCBIST == type )
            {
                TARGETING::getAllChiplets( list, TYPE_MCBIST );
            }
            else if ( fapi2::TARGET_TYPE_OCMB_CHIP == type )
            {
                TARGETING::getAllChips( list, TYPE_OCMB_CHIP );
            }

            if( !list.empty() )
            {
                mba = mbaList[0];
                err = getDiagnosticMode(
                                globals, mba, mode);

                if(err)
                {
                    TS_FAIL("getDiagnosticMode "
                            "failed unexpectedly");
                }

                if(mode != ONE_PATTERN)
                {
                    TS_FAIL("mode != ONE_PATTERN");
                }
            }

            WorkFlow wf, expected;

            expected.push_back(RESTORE_DRAM_REPAIRS);
            expected.push_back(START_PATTERN_0);
            expected.push_back(START_SCRUB);
            expected.push_back(CLEAR_HW_CHANGED_STATE);

            err = getWorkFlow(mode, wf, globals);

            if(err)
            {
                TS_FAIL("getWorkFlow failed unexpectedly");
            }

            if(wf.size() != expected.size())
            {
                TS_FAIL("incorrect workflow size for init only mode");
            }

            int64_t index = wf.size();

            while(index-- != 0)
            {
                if(wf[index] != expected[index])
                {
                    TS_FAIL("workflow entry incorrect or out of order");
                }
            }

            TS_TRACE(EXIT_MRK "testGetWorkFlow");
        }
};
#endif
<|endoftext|>


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

// checksum 0xdf1f version 0x10008
#include "qmlapplicationviewer.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtDeclarative/QDeclarativeComponent>
#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeContext>

#if defined(QMLJSDEBUGGER)
#include <jsdebuggeragent.h>
#endif
#if defined(QMLOBSERVER)
#include <qdeclarativeviewobserver.h>
#endif

#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
#include <eikenv.h>
#include <eikappui.h>
#include <aknenv.h>
#include <aknappui.h>
#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK

class QmlApplicationViewerPrivate
{
    QString mainQmlFile;
    friend class QmlApplicationViewer;
    static QString adjustPath(const QString &path);
};

QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
    if (!QDir::isAbsolutePath(path))
        return QCoreApplication::applicationDirPath()
                + QLatin1String("/../Resources/") + path;
#else
    const QString pathInShareDir = QCoreApplication::applicationDirPath()
        + QLatin1String("/../share/")
        + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
        + QLatin1Char('/') + path;
    if (QFileInfo(pathInShareDir).exists())
        return pathInShareDir;
#endif
#endif
    return path;
}

QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
    QDeclarativeView(parent),
    m_d(new QmlApplicationViewerPrivate)
{
    connect(engine(), SIGNAL(quit()), SLOT(close()));
    setResizeMode(QDeclarativeView::SizeRootObjectToView);
#ifdef QMLJSDEBUGGER
    new QmlJSDebugger::JSDebuggerAgent(engine());
#endif
#ifdef QMLOBSERVER
    new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
#endif
}

QmlApplicationViewer::~QmlApplicationViewer()
{
    delete m_d;
}

void QmlApplicationViewer::setMainQmlFile(const QString &file)
{
    m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
    setSource(QUrl(m_d->mainQmlFile));
}

void QmlApplicationViewer::addImportPath(const QString &path)
{
    engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
}

void QmlApplicationViewer::setOrientation(Orientation orientation)
{
#ifdef Q_OS_SYMBIAN
    if (orientation != Auto) {
#if defined(ORIENTATIONLOCK)
        const CAknAppUiBase::TAppUiOrientation uiOrientation =
                (orientation == LockPortrait) ? CAknAppUi::EAppUiOrientationPortrait
                    : CAknAppUi::EAppUiOrientationLandscape;
        CAknAppUi* appUi = dynamic_cast<CAknAppUi*> (CEikonEnv::Static()->AppUi());
        TRAPD(error,
            if (appUi)
                appUi->SetOrientationL(uiOrientation);
        );
#else // ORIENTATIONLOCK
        qWarning("'ORIENTATIONLOCK' needs to be defined on Symbian when locking the orientation.");
#endif // ORIENTATIONLOCK
    }
#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    Qt::WidgetAttribute attribute;
    switch (orientation) {
    case LockPortrait:
        attribute = Qt::WA_Maemo5PortraitOrientation;
        break;
    case LockLandscape:
        attribute = Qt::WA_Maemo5LandscapeOrientation;
        break;
    case Auto:
    default:
        attribute = Qt::WA_Maemo5AutoOrientation;
        break;
    }
    setAttribute(attribute, true);
#else // Q_OS_SYMBIAN
    Q_UNUSED(orientation);
#endif // Q_OS_SYMBIAN
}

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

// checksum 0xdf1f version 0x10008
#include "qmlapplicationviewer.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtDeclarative/QDeclarativeComponent>
#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeContext>

#if defined(QMLJSDEBUGGER)
#include <jsdebuggeragent.h>
#endif
#if defined(QMLOBSERVER)
#include <qdeclarativeviewobserver.h>
#endif

#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
#include <eikenv.h>
#include <eikappui.h>
#include <aknenv.h>
#include <aknappui.h>
#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK

class QmlApplicationViewerPrivate
{
    QString mainQmlFile;
    friend class QmlApplicationViewer;
    static QString adjustPath(const QString &path);
};

QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
    if (!QDir::isAbsolutePath(path))
        return QCoreApplication::applicationDirPath()
                + QLatin1String("/../Resources/") + path;
#else
    const QString pathInShareDir = QCoreApplication::applicationDirPath()
        + QLatin1String("/../share/")
        + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
        + QLatin1Char('/') + path;
    if (QFileInfo(pathInShareDir).exists())
        return pathInShareDir;
#endif
#endif
    return path;
}

QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
    QDeclarativeView(parent),
    m_d(new QmlApplicationViewerPrivate)
{
    connect(engine(), SIGNAL(quit()), SLOT(close()));
    setResizeMode(QDeclarativeView::SizeRootObjectToView);
#ifdef QMLJSDEBUGGER
    new QmlJSDebugger::JSDebuggerAgent(engine());
#endif
#ifdef QMLOBSERVER
    new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
#endif
}

QmlApplicationViewer::~QmlApplicationViewer()
{
    delete m_d;
}

void QmlApplicationViewer::setMainQmlFile(const QString &file)
{
    m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
    setSource(QUrl(m_d->mainQmlFile));
}

void QmlApplicationViewer::addImportPath(const QString &path)
{
    engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
}

void QmlApplicationViewer::setOrientation(Orientation orientation)
{
#ifdef Q_OS_SYMBIAN
    if (orientation != Auto) {
#if defined(ORIENTATIONLOCK)
        const CAknAppUiBase::TAppUiOrientation uiOrientation =
                (orientation == LockPortrait) ? CAknAppUi::EAppUiOrientationPortrait
                    : CAknAppUi::EAppUiOrientationLandscape;
        CAknAppUi* appUi = dynamic_cast<CAknAppUi*> (CEikonEnv::Static()->AppUi());
        TRAPD(error,
            if (appUi)
                appUi->SetOrientationL(uiOrientation);
        );
#else // ORIENTATIONLOCK
        qWarning("'ORIENTATIONLOCK' needs to be defined on Symbian when locking the orientation.");
#endif // ORIENTATIONLOCK
    }
#elif defined(Q_WS_MAEMO_5)
    Qt::WidgetAttribute attribute;
    switch (orientation) {
    case LockPortrait:
        attribute = Qt::WA_Maemo5PortraitOrientation;
        break;
    case LockLandscape:
        attribute = Qt::WA_Maemo5LandscapeOrientation;
        break;
    case Auto:
    default:
        attribute = Qt::WA_Maemo5AutoOrientation;
        break;
    }
    setAttribute(attribute, true);
#else // Q_OS_SYMBIAN
    Q_UNUSED(orientation);
#endif // Q_OS_SYMBIAN
}

void QmlApplicationViewer::show()
{
#ifdef Q_OS_SYMBIAN
    showFullScreen();
#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    showMaximized();
#else
    QDeclarativeView::show();
#endif
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "event/DeferEvent.hxx"
#include "util/BindMethod.hxx"

#include <boost/intrusive/list.hpp>

class LimitedConcurrencyQueue;

class LimitedConcurrencyJob final : public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
	friend class LimitedConcurrencyQueue;

	LimitedConcurrencyQueue &queue;

	const BoundMethod<void() noexcept> callback;

	enum class State {
		NONE,
		WAITING,
		RUNNING,
	} state = State::NONE;

public:
	LimitedConcurrencyJob(LimitedConcurrencyQueue &_queue,
			      BoundMethod<void() noexcept> _callback) noexcept
		:queue(_queue), callback(_callback) {}

	~LimitedConcurrencyJob() noexcept {
		Cancel();
	}

	LimitedConcurrencyJob(const LimitedConcurrencyJob &) = delete;
	LimitedConcurrencyJob &operator=(const LimitedConcurrencyJob &) = delete;

	bool IsWaiting() const noexcept {
		return state == State::WAITING;
	}

	bool IsRunning() const noexcept {
		return state == State::RUNNING;
	}

	void Schedule() noexcept;
	void Cancel() noexcept;
};

class LimitedConcurrencyQueue {
	using JobList =
		boost::intrusive::list<LimitedConcurrencyJob,
				       boost::intrusive::constant_time_size<true>>;

	JobList waiting, running;

	DeferEvent defer_start;

	const std::size_t concurrency_limit;

public:
	LimitedConcurrencyQueue(EventLoop &event_loop,
				std::size_t _limit) noexcept
		:defer_start(event_loop, BIND_THIS_METHOD(OnDeferredStart)),
		 concurrency_limit(_limit) {}

	~LimitedConcurrencyQueue() noexcept;

	void Add(LimitedConcurrencyJob &job) noexcept;
	void Remove(LimitedConcurrencyJob &job) noexcept;

private:
	void OnDeferredStart() noexcept;
};
<commit_msg>util/LimitedConcurrencyQueue: use class IntrusiveList<commit_after>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "event/DeferEvent.hxx"
#include "util/BindMethod.hxx"
#include "util/IntrusiveList.hxx"

class LimitedConcurrencyQueue;

class LimitedConcurrencyJob final : public IntrusiveListHook {
	friend class LimitedConcurrencyQueue;

	LimitedConcurrencyQueue &queue;

	const BoundMethod<void() noexcept> callback;

	enum class State {
		NONE,
		WAITING,
		RUNNING,
	} state = State::NONE;

public:
	LimitedConcurrencyJob(LimitedConcurrencyQueue &_queue,
			      BoundMethod<void() noexcept> _callback) noexcept
		:queue(_queue), callback(_callback) {}

	~LimitedConcurrencyJob() noexcept {
		Cancel();
	}

	LimitedConcurrencyJob(const LimitedConcurrencyJob &) = delete;
	LimitedConcurrencyJob &operator=(const LimitedConcurrencyJob &) = delete;

	bool IsWaiting() const noexcept {
		return state == State::WAITING;
	}

	bool IsRunning() const noexcept {
		return state == State::RUNNING;
	}

	void Schedule() noexcept;
	void Cancel() noexcept;
};

class LimitedConcurrencyQueue {
	using JobList =
		IntrusiveList<LimitedConcurrencyJob,
			      IntrusiveListBaseHookTraits<LimitedConcurrencyJob>,
			      true>;

	JobList waiting, running;

	DeferEvent defer_start;

	const std::size_t concurrency_limit;

public:
	LimitedConcurrencyQueue(EventLoop &event_loop,
				std::size_t _limit) noexcept
		:defer_start(event_loop, BIND_THIS_METHOD(OnDeferredStart)),
		 concurrency_limit(_limit) {}

	~LimitedConcurrencyQueue() noexcept;

	void Add(LimitedConcurrencyJob &job) noexcept;
	void Remove(LimitedConcurrencyJob &job) noexcept;

private:
	void OnDeferredStart() noexcept;
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "FabricUIManager.h"

#include <glog/logging.h>

#include <fabric/core/componentDescriptor.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/debug/DebugStringConvertible.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <fabric/view/ViewComponentDescriptor.h>
#include <fabric/view/ViewProps.h>
#include <fabric/view/ViewShadowNode.h>

namespace facebook {
namespace react {

// TODO: Kill this flag and remove debug logging.
const bool isLoggingEnabled = false;

static const RawProps rawPropsFromDynamic(const folly::dynamic object) {
  // TODO: Convert this to something smarter, probably returning `std::iterator`.
  RawProps result;

  if (object.isNull()) {
    return result;
  }

  assert(object.isObject());

  for (const auto &pair : object.items()) {
    assert(pair.first.isString());
    result[pair.first.asString()] = pair.second;
  }

  return result;
}

static const std::string componentNameByReactViewName(std::string viewName) {
  // We need this function only for the transition period;
  // eventually, all names will be unified.

  std::string rctPrefix("RCT");
  if (std::mismatch(rctPrefix.begin(), rctPrefix.end(), viewName.begin()).first == rctPrefix.end()) {
    // If `viewName` has "RCT" prefix, remove it.
    viewName.erase(0, rctPrefix.length());
  }

  // Fabric uses slightly new names for Text components because of differences
  // in semantic.
  if (viewName == "Text") {
    return "Paragraph";
  }
  if (viewName == "VirtualText") {
    return "Text";
  }

  if (viewName == "ImageView") {
    return "Image";
  }

  // We need this temporarly for testing purposes until we have proper
  // implementation of core components: <ReactPerformanceLoggerFlag>,
  // <SafeAreaView>, and etc.
  if (
    viewName == "ReactPerformanceLoggerFlag" ||
    viewName == "SinglelineTextInputView" ||
    viewName == "MultilineTextInputView" ||
    viewName == "RefreshControl" ||
    viewName == "SafeAreaView" ||
    viewName == "ScrollContentView"
  ) {
    return "View";
  }

  return viewName;
}

FabricUIManager::FabricUIManager(SharedComponentDescriptorRegistry componentDescriptorRegistry) {
  componentDescriptorRegistry_ = componentDescriptorRegistry;
}

FabricUIManager::~FabricUIManager() {
  if (eventHandler_) {
    releaseEventHandlerFunction_(eventHandler_);
  }
}

void FabricUIManager::setDelegate(UIManagerDelegate *delegate) {
  delegate_ = delegate;
}

UIManagerDelegate *FabricUIManager::getDelegate() {
  return delegate_;
}

void FabricUIManager::setCreateEventTargetFunction(std::function<CreateEventTargetFunction> createEventTargetFunction) {
  createEventTargetFunction_ = createEventTargetFunction;
}

void FabricUIManager::setDispatchEventFunction(std::function<DispatchEventFunction> dispatchEventFunction) {
  dispatchEventFunction_ = dispatchEventFunction;
}

void FabricUIManager::setReleaseEventHandlerFunction(std::function<ReleaseEventHandlerFunction> releaseEventHandlerFunction) {
  releaseEventHandlerFunction_ = releaseEventHandlerFunction;
}

void FabricUIManager::setReleaseEventTargetFunction(std::function<ReleaseEventTargetFunction> releaseEventTargetFunction) {
  releaseEventTargetFunction_ = releaseEventTargetFunction;
}

EventTarget FabricUIManager::createEventTarget(const InstanceHandle &instanceHandle) const {
  return createEventTargetFunction_(instanceHandle);
}

void FabricUIManager::dispatchEvent(const EventTarget &eventTarget, const std::string &type, const folly::dynamic &payload) const {
  dispatchEventFunction_(
    eventHandler_,
    eventTarget,
    const_cast<std::string &>(type),
    const_cast<folly::dynamic &>(payload)
  );
}

void FabricUIManager::releaseEventTarget(const EventTarget &eventTarget) const {
  releaseEventTargetFunction_(eventTarget);
}

SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int rootTag, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode(tag: " << tag << ", name: " << viewName << ", rootTag: " << rootTag << ", props: " << props << ")";

  ComponentName componentName = componentNameByReactViewName(viewName);
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[componentName];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode shadowNode =
    componentDescriptor->createShadowNode(
      tag,
      rootTag,
      componentDescriptor->createEventEmitter(instanceHandle, tag),
      componentDescriptor->cloneProps(nullptr, rawProps)
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode() -> " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});

  if (delegate_) {
    delegate_->uiManagerDidCreateShadowNode(shadowNode);
  }

  return shadowNode;
}

SharedShadowNode FabricUIManager::cloneNode(const SharedShadowNode &shadowNode, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      nullptr,
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      nullptr
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewChildren(const SharedShadowNode &shadowNode, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  // Assuming semantic: Cloning with same props but empty children.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      nullptr,
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      ShadowNode::emptySharedShadowNodeSharedList()
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewProps(const SharedShadowNode &shadowNode, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")";
  // Assuming semantic: Cloning with same children and specified props.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      componentDescriptor->cloneProps(shadowNode->getProps(), rawProps),
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      nullptr
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewChildrenAndProps(const SharedShadowNode &shadowNode, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")";
  // Assuming semantic: Cloning with empty children and specified props.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      componentDescriptor->cloneProps(shadowNode->getProps(), rawProps),
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      ShadowNode::emptySharedShadowNodeSharedList()
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

void FabricUIManager::appendChild(const SharedShadowNode &parentShadowNode, const SharedShadowNode &childShadowNode) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChild(parentShadowNode: " << parentShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", childShadowNode: " << childShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[parentShadowNode];

  // TODO: Remove this after we move this to JS side.
  if (childShadowNode->getSealed()) {
    auto childComponentDescriptor = (*componentDescriptorRegistry_)[childShadowNode];
    auto clonedChildShadowNode = childComponentDescriptor->cloneShadowNode(childShadowNode);
    auto nonConstClonedChildShadowNode = std::const_pointer_cast<ShadowNode>(clonedChildShadowNode);
    nonConstClonedChildShadowNode->shallowSourceNode();
    componentDescriptor->appendChild(parentShadowNode, clonedChildShadowNode);
    return;
  }

  componentDescriptor->appendChild(parentShadowNode, childShadowNode);
}

SharedShadowNodeUnsharedList FabricUIManager::createChildSet(int rootTag) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createChildSet(rootTag: " << rootTag << ")";
  return std::make_shared<SharedShadowNodeList>(SharedShadowNodeList({}));
}

void FabricUIManager::appendChildToSet(const SharedShadowNodeUnsharedList &shadowNodeList, const SharedShadowNode &shadowNode) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChildToSet(shadowNodeList: " << shadowNodeList << ", shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  shadowNodeList->push_back(shadowNode);
}

void FabricUIManager::completeRoot(int rootTag, const SharedShadowNodeUnsharedList &children) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::completeRoot(rootTag: " << rootTag << ", shadowNodeList: " << children << ")";

  if (delegate_) {
    delegate_->uiManagerDidFinishTransaction(rootTag, children);
  }
}

void FabricUIManager::registerEventHandler(const EventHandler &eventHandler) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::registerEventHandler(eventHandler: " << eventHandler << ")";
  eventHandler_ = eventHandler;
}

} // namespace react
} // namespace facebook
<commit_msg>Fabric: Shadow node shallowing was removed from preventive cloning in UIManager<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "FabricUIManager.h"

#include <glog/logging.h>

#include <fabric/core/componentDescriptor.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/debug/DebugStringConvertible.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <fabric/view/ViewComponentDescriptor.h>
#include <fabric/view/ViewProps.h>
#include <fabric/view/ViewShadowNode.h>

namespace facebook {
namespace react {

// TODO: Kill this flag and remove debug logging.
const bool isLoggingEnabled = false;

static const RawProps rawPropsFromDynamic(const folly::dynamic object) {
  // TODO: Convert this to something smarter, probably returning `std::iterator`.
  RawProps result;

  if (object.isNull()) {
    return result;
  }

  assert(object.isObject());

  for (const auto &pair : object.items()) {
    assert(pair.first.isString());
    result[pair.first.asString()] = pair.second;
  }

  return result;
}

static const std::string componentNameByReactViewName(std::string viewName) {
  // We need this function only for the transition period;
  // eventually, all names will be unified.

  std::string rctPrefix("RCT");
  if (std::mismatch(rctPrefix.begin(), rctPrefix.end(), viewName.begin()).first == rctPrefix.end()) {
    // If `viewName` has "RCT" prefix, remove it.
    viewName.erase(0, rctPrefix.length());
  }

  // Fabric uses slightly new names for Text components because of differences
  // in semantic.
  if (viewName == "Text") {
    return "Paragraph";
  }
  if (viewName == "VirtualText") {
    return "Text";
  }

  if (viewName == "ImageView") {
    return "Image";
  }

  // We need this temporarly for testing purposes until we have proper
  // implementation of core components: <ReactPerformanceLoggerFlag>,
  // <SafeAreaView>, and etc.
  if (
    viewName == "ReactPerformanceLoggerFlag" ||
    viewName == "SinglelineTextInputView" ||
    viewName == "MultilineTextInputView" ||
    viewName == "RefreshControl" ||
    viewName == "SafeAreaView" ||
    viewName == "ScrollContentView"
  ) {
    return "View";
  }

  return viewName;
}

FabricUIManager::FabricUIManager(SharedComponentDescriptorRegistry componentDescriptorRegistry) {
  componentDescriptorRegistry_ = componentDescriptorRegistry;
}

FabricUIManager::~FabricUIManager() {
  if (eventHandler_) {
    releaseEventHandlerFunction_(eventHandler_);
  }
}

void FabricUIManager::setDelegate(UIManagerDelegate *delegate) {
  delegate_ = delegate;
}

UIManagerDelegate *FabricUIManager::getDelegate() {
  return delegate_;
}

void FabricUIManager::setCreateEventTargetFunction(std::function<CreateEventTargetFunction> createEventTargetFunction) {
  createEventTargetFunction_ = createEventTargetFunction;
}

void FabricUIManager::setDispatchEventFunction(std::function<DispatchEventFunction> dispatchEventFunction) {
  dispatchEventFunction_ = dispatchEventFunction;
}

void FabricUIManager::setReleaseEventHandlerFunction(std::function<ReleaseEventHandlerFunction> releaseEventHandlerFunction) {
  releaseEventHandlerFunction_ = releaseEventHandlerFunction;
}

void FabricUIManager::setReleaseEventTargetFunction(std::function<ReleaseEventTargetFunction> releaseEventTargetFunction) {
  releaseEventTargetFunction_ = releaseEventTargetFunction;
}

EventTarget FabricUIManager::createEventTarget(const InstanceHandle &instanceHandle) const {
  return createEventTargetFunction_(instanceHandle);
}

void FabricUIManager::dispatchEvent(const EventTarget &eventTarget, const std::string &type, const folly::dynamic &payload) const {
  dispatchEventFunction_(
    eventHandler_,
    eventTarget,
    const_cast<std::string &>(type),
    const_cast<folly::dynamic &>(payload)
  );
}

void FabricUIManager::releaseEventTarget(const EventTarget &eventTarget) const {
  releaseEventTargetFunction_(eventTarget);
}

SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int rootTag, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode(tag: " << tag << ", name: " << viewName << ", rootTag: " << rootTag << ", props: " << props << ")";

  ComponentName componentName = componentNameByReactViewName(viewName);
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[componentName];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode shadowNode =
    componentDescriptor->createShadowNode(
      tag,
      rootTag,
      componentDescriptor->createEventEmitter(instanceHandle, tag),
      componentDescriptor->cloneProps(nullptr, rawProps)
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode() -> " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});

  if (delegate_) {
    delegate_->uiManagerDidCreateShadowNode(shadowNode);
  }

  return shadowNode;
}

SharedShadowNode FabricUIManager::cloneNode(const SharedShadowNode &shadowNode, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      nullptr,
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      nullptr
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewChildren(const SharedShadowNode &shadowNode, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  // Assuming semantic: Cloning with same props but empty children.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      nullptr,
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      ShadowNode::emptySharedShadowNodeSharedList()
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewProps(const SharedShadowNode &shadowNode, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")";
  // Assuming semantic: Cloning with same children and specified props.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      componentDescriptor->cloneProps(shadowNode->getProps(), rawProps),
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      nullptr
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

SharedShadowNode FabricUIManager::cloneNodeWithNewChildrenAndProps(const SharedShadowNode &shadowNode, folly::dynamic props, InstanceHandle instanceHandle) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")";
  // Assuming semantic: Cloning with empty children and specified props.
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode];
  RawProps rawProps = rawPropsFromDynamic(props);

  SharedShadowNode clonedShadowNode =
    componentDescriptor->cloneShadowNode(
      shadowNode,
      componentDescriptor->cloneProps(shadowNode->getProps(), rawProps),
      componentDescriptor->createEventEmitter(instanceHandle, shadowNode->getTag()),
      ShadowNode::emptySharedShadowNodeSharedList()
    );

  isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false});
  return clonedShadowNode;
}

void FabricUIManager::appendChild(const SharedShadowNode &parentShadowNode, const SharedShadowNode &childShadowNode) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChild(parentShadowNode: " << parentShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", childShadowNode: " << childShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[parentShadowNode];

  // TODO: Remove this after we move this to JS side.
  if (childShadowNode->getSealed()) {
    auto childComponentDescriptor = (*componentDescriptorRegistry_)[childShadowNode];
    auto clonedChildShadowNode = childComponentDescriptor->cloneShadowNode(childShadowNode);
    auto nonConstClonedChildShadowNode = std::const_pointer_cast<ShadowNode>(clonedChildShadowNode);
    componentDescriptor->appendChild(parentShadowNode, clonedChildShadowNode);
    return;
  }

  componentDescriptor->appendChild(parentShadowNode, childShadowNode);
}

SharedShadowNodeUnsharedList FabricUIManager::createChildSet(int rootTag) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::createChildSet(rootTag: " << rootTag << ")";
  return std::make_shared<SharedShadowNodeList>(SharedShadowNodeList({}));
}

void FabricUIManager::appendChildToSet(const SharedShadowNodeUnsharedList &shadowNodeList, const SharedShadowNode &shadowNode) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChildToSet(shadowNodeList: " << shadowNodeList << ", shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")";
  shadowNodeList->push_back(shadowNode);
}

void FabricUIManager::completeRoot(int rootTag, const SharedShadowNodeUnsharedList &children) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::completeRoot(rootTag: " << rootTag << ", shadowNodeList: " << children << ")";

  if (delegate_) {
    delegate_->uiManagerDidFinishTransaction(rootTag, children);
  }
}

void FabricUIManager::registerEventHandler(const EventHandler &eventHandler) {
  isLoggingEnabled && LOG(INFO) << "FabricUIManager::registerEventHandler(eventHandler: " << eventHandler << ")";
  eventHandler_ = eventHandler;
}

} // namespace react
} // namespace facebook
<|endoftext|>


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

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

#ifndef _DBAUI_ODBC_CONFIG_HXX_
#include "odbcconfig.hxx"
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifdef HAVE_ODBC_SUPPORT

#ifdef WIN
#define ODBC_LIBRARY    "ODBC.DLL"
#define ODBC_UI_LIBRARY "ODBCINST.DLL"
#endif
#if defined WNT
#define ODBC_LIBRARY    "ODBC32.DLL"
#define ODBC_UI_LIBRARY "ODBCCP32.DLL"
#endif
#ifdef UNX
#ifdef MACOSX
#define ODBC_LIBRARY        "libiodbc.dylib"
#define ODBC_UI_LIBRARY     "libiodbcinst.dylib"
#else
#define ODBC_LIBRARY_1      "libodbc.so.1"
#define ODBC_UI_LIBRARY_1   "libodbcinst.so.1"
#define ODBC_LIBRARY        "libodbc.so"
#define ODBC_UI_LIBRARY     "libodbcinst.so"
#endif
#endif

// just to go with calling convention of windows
// so don't touch this
#if defined(WIN) || defined(WNT)
#define SQL_API __stdcall
// At least under some circumstances, the below #include <odbc/sqlext.h> re-
// defines SQL_API to an empty string, leading to a compiler warning on MSC; to
// not break the current behavior, this is worked around by locally disabling
// that warning:
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4005)
#endif
#endif // defined(WIN) || defined(WNT)

#ifdef SYSTEM_ODBC_HEADERS
#include <sqlext.h>
#else
#ifndef __SQLEXT_H
#include <odbc/sqlext.h>
#endif
#endif

#if defined(WIN) || defined(WNT)
#if defined _MSC_VER
#pragma warning(pop)
#endif
#undef SQL_API
#define SQL_API __stdcall
#endif // defined(WIN) || defined(WNT)
// from here on you can do what you want to

#else

#define ODBC_LIBRARY    ""
#define ODBC_UI_LIBRARY ""

#endif  // HAVE_ODBC_SUPPORT

//.........................................................................
namespace dbaui
{
//.........................................................................

#ifdef HAVE_ODBC_SUPPORT
typedef SQLRETURN (SQL_API* TSQLManageDataSource) (SQLHWND hwndParent);
typedef SQLRETURN (SQL_API* TSQLAllocHandle) (SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE* OutputHandlePtr);
typedef SQLRETURN (SQL_API* TSQLFreeHandle) (SQLSMALLINT HandleType, SQLHANDLE Handle);
typedef SQLRETURN (SQL_API* TSQLSetEnvAttr) (SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
typedef SQLRETURN (SQL_API* TSQLDataSources) (SQLHENV EnvironmentHandle, SQLUSMALLINT   Direction, SQLCHAR* ServerName,
                                SQLSMALLINT BufferLength1, SQLSMALLINT* NameLength1Ptr, SQLCHAR* Description, SQLSMALLINT BufferLength2, SQLSMALLINT* NameLength2Ptr);

#define NSQLManageDataSource(a) (*(TSQLManageDataSource)(m_pSQLManageDataSource))(a)
#define NSQLAllocHandle(a,b,c) (*(TSQLAllocHandle)(m_pAllocHandle))(a,b,c)
#define NSQLFreeHandle(a,b) (*(TSQLFreeHandle)(m_pFreeHandle))(a,b)
#define NSQLSetEnvAttr(a,b,c,d) (*(TSQLSetEnvAttr)(m_pSetEnvAttr))(a,b,c,d)
#define NSQLDataSources(a,b,c,d,e,f,g,h) (*(TSQLDataSources)(m_pDataSources))(a,b,c,d,e,f,g,h)
#endif

//=========================================================================
//= OOdbcLibWrapper
//=========================================================================
DBG_NAME(OOdbcLibWrapper)
//-------------------------------------------------------------------------
OOdbcLibWrapper::OOdbcLibWrapper()
    :m_pOdbcLib(NULL)
{
    DBG_CTOR(OOdbcLibWrapper,NULL);

}

//-------------------------------------------------------------------------
sal_Bool OOdbcLibWrapper::load(const sal_Char* _pLibPath)
{
    m_sLibPath = ::rtl::OUString::createFromAscii(_pLibPath);
#ifdef HAVE_ODBC_SUPPORT
    // load the module
    m_pOdbcLib = osl_loadModule(m_sLibPath.pData, SAL_LOADMODULE_NOW);
    return (NULL != m_pOdbcLib);
#endif
}

//-------------------------------------------------------------------------
void OOdbcLibWrapper::unload()
{
#ifdef HAVE_ODBC_SUPPORT
    if (isLoaded())
    {
        osl_unloadModule(m_pOdbcLib);
        m_pOdbcLib = NULL;
    }
#endif
}

//-------------------------------------------------------------------------
oslGenericFunction OOdbcLibWrapper::loadSymbol(const sal_Char* _pFunctionName)
{
    return osl_getFunctionSymbol(m_pOdbcLib, ::rtl::OUString::createFromAscii(_pFunctionName).pData);
}

//-------------------------------------------------------------------------
OOdbcLibWrapper::~OOdbcLibWrapper()
{
    unload();

    DBG_DTOR(OOdbcLibWrapper,NULL);
}

//=========================================================================
//= OOdbcEnumeration
//=========================================================================
struct OdbcTypesImpl
{
#ifdef HAVE_ODBC_SUPPORT
    SQLHANDLE   hEnvironment;
    OdbcTypesImpl() : hEnvironment(0) { }
#else
    void*       pDummy;
#endif
};
DBG_NAME(OOdbcEnumeration)
//-------------------------------------------------------------------------
OOdbcEnumeration::OOdbcEnumeration()
#ifdef HAVE_ODBC_SUPPORT
    :m_pAllocHandle(NULL)
    ,m_pSetEnvAttr(NULL)
    ,m_pDataSources(NULL)
    ,m_pImpl(new OdbcTypesImpl)
#endif
{
    DBG_CTOR(OOdbcEnumeration,NULL);

    sal_Bool bLoaded = load(ODBC_LIBRARY);
#ifdef ODBC_LIBRARY_1
    if ( !bLoaded )
        bLoaded = load(ODBC_LIBRARY_1);
#endif

    if ( bLoaded )
    {
#ifdef HAVE_ODBC_SUPPORT
        // load the generic functions
        m_pAllocHandle = loadSymbol("SQLAllocHandle");
        m_pFreeHandle = loadSymbol("SQLFreeHandle");
        m_pSetEnvAttr = loadSymbol("SQLSetEnvAttr");
        m_pDataSources = loadSymbol("SQLDataSources");

        // all or nothing
        if (!m_pAllocHandle || !m_pSetEnvAttr || !m_pDataSources || !m_pFreeHandle)
        {
            unload();
            m_pAllocHandle = m_pFreeHandle = m_pSetEnvAttr = m_pDataSources = NULL;
        }
#endif
    }
}

//-------------------------------------------------------------------------
OOdbcEnumeration::~OOdbcEnumeration()
{
    freeEnv();
    delete m_pImpl;

    DBG_DTOR(OOdbcEnumeration,NULL);
}

//-------------------------------------------------------------------------
sal_Bool OOdbcEnumeration::allocEnv()
{
    OSL_ENSURE(isLoaded(), "OOdbcEnumeration::allocEnv: not loaded!");
    if (!isLoaded())
        return sal_False;

#ifdef HAVE_ODBC_SUPPORT
    if (m_pImpl->hEnvironment)
        // nothing to do
        return sal_True;
    SQLRETURN nResult = NSQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_pImpl->hEnvironment);
    if (SQL_SUCCESS != nResult)
        // can't do anything without environment
        return sal_False;

    NSQLSetEnvAttr(m_pImpl->hEnvironment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
    return sal_True;
#else
    return sal_False;
#endif
}

//-------------------------------------------------------------------------
void OOdbcEnumeration::freeEnv()
{
#ifdef HAVE_ODBC_SUPPORT
    if (m_pImpl->hEnvironment)
        NSQLFreeHandle(SQL_HANDLE_ENV, m_pImpl->hEnvironment);
    m_pImpl->hEnvironment  = 0;
#endif
}

//-------------------------------------------------------------------------
void OOdbcEnumeration::getDatasourceNames(StringBag& _rNames)
{
    OSL_ENSURE(isLoaded(), "OOdbcManagement::getDatasourceNames: not loaded!");
    if (!isLoaded())
        return;

    if (!allocEnv())
    {
        OSL_ENSURE(sal_False, "OOdbcManagement::getDatasourceNames: could not allocate an ODBC environment!");
        return;
    }

#ifdef HAVE_ODBC_SUPPORT
    // now that we have an environment collect the data source names
    UCHAR szDSN[SQL_MAX_DSN_LENGTH+1];
    SWORD pcbDSN;
    UCHAR szDescription[1024+1];
    SWORD pcbDescription;
    SQLRETURN nResult = SQL_SUCCESS;

    for (   nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_FIRST, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription), &pcbDescription);
            ;
            nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_NEXT, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription), &pcbDescription)
        )
    {
        if (nResult != SQL_SUCCESS)
            // no further error handling
            break;
        else
        {
            ::rtl::OUStringBuffer aCurrentDsn; aCurrentDsn.appendAscii(reinterpret_cast<const char*>(szDSN));
            _rNames.insert(aCurrentDsn.makeStringAndClear());
        }
    }
#endif
}

//=========================================================================
//= OOdbcManagement
//=========================================================================
//-------------------------------------------------------------------------
OOdbcManagement::OOdbcManagement()
#ifdef HAVE_ODBC_SUPPORT
:m_pSQLManageDataSource(NULL)
#endif
{
    sal_Bool bLoaded = load(ODBC_UI_LIBRARY);
#ifdef ODBC_UI_LIBRARY_1
    if ( !bLoaded )
        bLoaded = load(ODBC_UI_LIBRARY_1);
#endif
    if ( bLoaded )
    {
#ifdef HAVE_ODBC_SUPPORT
        m_pSQLManageDataSource = loadSymbol("SQLManageDataSources");
        if (!m_pSQLManageDataSource)
            unload();
#endif // HAVE_ODBC_SUPPORT
    }
}

//-------------------------------------------------------------------------
void OOdbcManagement::manageDataSources(void* _pParentSysWindowHandle)
{
    OSL_ENSURE(isLoaded(), "OOdbcManagement::manageDataSources: not loaded!");
    OSL_ENSURE(_pParentSysWindowHandle, "OOdbcManagement::manageDataSources: invalid parent window!");
    if (!isLoaded())
        return;

#ifdef HAVE_ODBC_SUPPORT
    NSQLManageDataSource(_pParentSysWindowHandle);
#endif // HAVE_ODBC_SUPPORT
}

//.........................................................................
}   // namespace dbaui
//.........................................................................
<commit_msg>INTEGRATION: CWS dba23b (1.17.88); FILE MERGED 2007/07/04 11:57:16 fs 1.17.88.2: #i10000# 2007/07/04 10:33:35 fs 1.17.88.1: #i78733# managing data sources now done by an external process<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: odbcconfig.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-24 12:08:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _DBAUI_ODBC_CONFIG_HXX_
#include "odbcconfig.hxx"
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _THREAD_HXX_
#include <osl/thread.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifdef HAVE_ODBC_SUPPORT

#ifdef WIN
#define ODBC_LIBRARY    "ODBC.DLL"
#define ODBC_UI_LIBRARY "ODBCINST.DLL"
#endif
#if defined WNT
#define ODBC_LIBRARY    "ODBC32.DLL"
#define ODBC_UI_LIBRARY "ODBCCP32.DLL"
#endif
#ifdef UNX
#ifdef MACOSX
#define ODBC_LIBRARY        "libiodbc.dylib"
#define ODBC_UI_LIBRARY     "libiodbcinst.dylib"
#else
#define ODBC_LIBRARY_1      "libodbc.so.1"
#define ODBC_UI_LIBRARY_1   "libodbcinst.so.1"
#define ODBC_LIBRARY        "libodbc.so"
#define ODBC_UI_LIBRARY     "libodbcinst.so"
#endif
#endif

// just to go with calling convention of windows
// so don't touch this
#if defined(WIN) || defined(WNT)
#define SQL_API __stdcall
// At least under some circumstances, the below #include <odbc/sqlext.h> re-
// defines SQL_API to an empty string, leading to a compiler warning on MSC; to
// not break the current behavior, this is worked around by locally disabling
// that warning:
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4005)
#endif
#endif // defined(WIN) || defined(WNT)

#ifdef SYSTEM_ODBC_HEADERS
#include <sqlext.h>
#else
#ifndef __SQLEXT_H
#include <odbc/sqlext.h>
#endif
#endif

#if defined(WIN) || defined(WNT)
#if defined _MSC_VER
#pragma warning(pop)
#endif
#undef SQL_API
#define SQL_API __stdcall
#endif // defined(WIN) || defined(WNT)
// from here on you can do what you want to

#else

#define ODBC_LIBRARY    ""
#define ODBC_UI_LIBRARY ""

#endif  // HAVE_ODBC_SUPPORT

//.........................................................................
namespace dbaui
{
//.........................................................................

#ifdef HAVE_ODBC_SUPPORT
typedef SQLRETURN (SQL_API* TSQLManageDataSource) (SQLHWND hwndParent);
typedef SQLRETURN (SQL_API* TSQLAllocHandle) (SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE* OutputHandlePtr);
typedef SQLRETURN (SQL_API* TSQLFreeHandle) (SQLSMALLINT HandleType, SQLHANDLE Handle);
typedef SQLRETURN (SQL_API* TSQLSetEnvAttr) (SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
typedef SQLRETURN (SQL_API* TSQLDataSources) (SQLHENV EnvironmentHandle, SQLUSMALLINT   Direction, SQLCHAR* ServerName,
                                SQLSMALLINT BufferLength1, SQLSMALLINT* NameLength1Ptr, SQLCHAR* Description, SQLSMALLINT BufferLength2, SQLSMALLINT* NameLength2Ptr);

#define NSQLManageDataSource(a) (*(TSQLManageDataSource)(m_pSQLManageDataSource))(a)
#define NSQLAllocHandle(a,b,c) (*(TSQLAllocHandle)(m_pAllocHandle))(a,b,c)
#define NSQLFreeHandle(a,b) (*(TSQLFreeHandle)(m_pFreeHandle))(a,b)
#define NSQLSetEnvAttr(a,b,c,d) (*(TSQLSetEnvAttr)(m_pSetEnvAttr))(a,b,c,d)
#define NSQLDataSources(a,b,c,d,e,f,g,h) (*(TSQLDataSources)(m_pDataSources))(a,b,c,d,e,f,g,h)
#endif

//=========================================================================
//= OOdbcLibWrapper
//=========================================================================
DBG_NAME(OOdbcLibWrapper)
//-------------------------------------------------------------------------
OOdbcLibWrapper::OOdbcLibWrapper()
    :m_pOdbcLib(NULL)
{
    DBG_CTOR(OOdbcLibWrapper,NULL);

}

//-------------------------------------------------------------------------
sal_Bool OOdbcLibWrapper::load(const sal_Char* _pLibPath)
{
    m_sLibPath = ::rtl::OUString::createFromAscii(_pLibPath);
#ifdef HAVE_ODBC_SUPPORT
    // load the module
    m_pOdbcLib = osl_loadModule(m_sLibPath.pData, SAL_LOADMODULE_NOW);
    return (NULL != m_pOdbcLib);
#endif
}

//-------------------------------------------------------------------------
void OOdbcLibWrapper::unload()
{
#ifdef HAVE_ODBC_SUPPORT
    if (isLoaded())
    {
        osl_unloadModule(m_pOdbcLib);
        m_pOdbcLib = NULL;
    }
#endif
}

//-------------------------------------------------------------------------
oslGenericFunction OOdbcLibWrapper::loadSymbol(const sal_Char* _pFunctionName)
{
    return osl_getFunctionSymbol(m_pOdbcLib, ::rtl::OUString::createFromAscii(_pFunctionName).pData);
}

//-------------------------------------------------------------------------
OOdbcLibWrapper::~OOdbcLibWrapper()
{
    unload();

    DBG_DTOR(OOdbcLibWrapper,NULL);
}

//=========================================================================
//= OOdbcEnumeration
//=========================================================================
struct OdbcTypesImpl
{
#ifdef HAVE_ODBC_SUPPORT
    SQLHANDLE   hEnvironment;
    OdbcTypesImpl() : hEnvironment(0) { }
#else
    void*       pDummy;
#endif
};
DBG_NAME(OOdbcEnumeration)
//-------------------------------------------------------------------------
OOdbcEnumeration::OOdbcEnumeration()
#ifdef HAVE_ODBC_SUPPORT
    :m_pAllocHandle(NULL)
    ,m_pSetEnvAttr(NULL)
    ,m_pDataSources(NULL)
    ,m_pImpl(new OdbcTypesImpl)
#endif
{
    DBG_CTOR(OOdbcEnumeration,NULL);

    sal_Bool bLoaded = load(ODBC_LIBRARY);
#ifdef ODBC_LIBRARY_1
    if ( !bLoaded )
        bLoaded = load(ODBC_LIBRARY_1);
#endif

    if ( bLoaded )
    {
#ifdef HAVE_ODBC_SUPPORT
        // load the generic functions
        m_pAllocHandle = loadSymbol("SQLAllocHandle");
        m_pFreeHandle = loadSymbol("SQLFreeHandle");
        m_pSetEnvAttr = loadSymbol("SQLSetEnvAttr");
        m_pDataSources = loadSymbol("SQLDataSources");

        // all or nothing
        if (!m_pAllocHandle || !m_pSetEnvAttr || !m_pDataSources || !m_pFreeHandle)
        {
            unload();
            m_pAllocHandle = m_pFreeHandle = m_pSetEnvAttr = m_pDataSources = NULL;
        }
#endif
    }
}

//-------------------------------------------------------------------------
OOdbcEnumeration::~OOdbcEnumeration()
{
    freeEnv();
    delete m_pImpl;

    DBG_DTOR(OOdbcEnumeration,NULL);
}

//-------------------------------------------------------------------------
sal_Bool OOdbcEnumeration::allocEnv()
{
    OSL_ENSURE(isLoaded(), "OOdbcEnumeration::allocEnv: not loaded!");
    if (!isLoaded())
        return sal_False;

#ifdef HAVE_ODBC_SUPPORT
    if (m_pImpl->hEnvironment)
        // nothing to do
        return sal_True;
    SQLRETURN nResult = NSQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_pImpl->hEnvironment);
    if (SQL_SUCCESS != nResult)
        // can't do anything without environment
        return sal_False;

    NSQLSetEnvAttr(m_pImpl->hEnvironment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
    return sal_True;
#else
    return sal_False;
#endif
}

//-------------------------------------------------------------------------
void OOdbcEnumeration::freeEnv()
{
#ifdef HAVE_ODBC_SUPPORT
    if (m_pImpl->hEnvironment)
        NSQLFreeHandle(SQL_HANDLE_ENV, m_pImpl->hEnvironment);
    m_pImpl->hEnvironment  = 0;
#endif
}

//-------------------------------------------------------------------------
void OOdbcEnumeration::getDatasourceNames(StringBag& _rNames)
{
    OSL_ENSURE(isLoaded(), "OOdbcEnumeration::getDatasourceNames: not loaded!");
    if (!isLoaded())
        return;

    if (!allocEnv())
    {
        OSL_ENSURE(sal_False, "OOdbcEnumeration::getDatasourceNames: could not allocate an ODBC environment!");
        return;
    }

#ifdef HAVE_ODBC_SUPPORT
    // now that we have an environment collect the data source names
    UCHAR szDSN[SQL_MAX_DSN_LENGTH+1];
    SWORD pcbDSN;
    UCHAR szDescription[1024+1];
    SWORD pcbDescription;
    SQLRETURN nResult = SQL_SUCCESS;

    for (   nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_FIRST, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription), &pcbDescription);
            ;
            nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_NEXT, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription), &pcbDescription)
        )
    {
        if (nResult != SQL_SUCCESS)
            // no further error handling
            break;
        else
        {
            ::rtl::OUStringBuffer aCurrentDsn; aCurrentDsn.appendAscii(reinterpret_cast<const char*>(szDSN));
            _rNames.insert(aCurrentDsn.makeStringAndClear());
        }
    }
#endif
}

#ifdef HAVE_ODBC_ADMINISTRATION

//=========================================================================
//= ProcessTerminationWait
//=========================================================================
class ProcessTerminationWait : public ::osl::Thread
{
    oslProcess  m_hProcessHandle;
    Link        m_aFinishHdl;

public:
    ProcessTerminationWait( oslProcess _hProcessHandle, const Link& _rFinishHdl )
        :m_hProcessHandle( _hProcessHandle )
        ,m_aFinishHdl( _rFinishHdl )
    {
    }

protected:
    virtual void SAL_CALL run()
    {
        osl_joinProcess( m_hProcessHandle );
        Application::PostUserEvent( m_aFinishHdl );
    }
};

//=========================================================================
//= OOdbcManagement
//=========================================================================
//-------------------------------------------------------------------------
OOdbcManagement::OOdbcManagement( const Link& _rAsyncFinishCallback )
    :m_pProcessWait( NULL )
    ,m_aAsyncFinishCallback( _rAsyncFinishCallback )
{
}

//-------------------------------------------------------------------------
OOdbcManagement::~OOdbcManagement()
{
    // wait for our thread to be finished
    if ( m_pProcessWait.get() )
        m_pProcessWait->join();
}

//-------------------------------------------------------------------------
bool OOdbcManagement::manageDataSources_async()
{
    OSL_PRECOND( !isRunning(), "OOdbcManagement::manageDataSources_async: still running from the previous call!" );
    if ( isRunning() )
        return false;

    // this is done in an external process, due to #i78733#
    // (and note this whole functionality is supported on Windows only, ATM)
    ::rtl::OUString sExecutableName( RTL_CONSTASCII_USTRINGPARAM( "odbcconfig.exe" ) );
    oslProcess hProcessHandle(0);
    oslProcessError eError = osl_executeProcess( sExecutableName.pData, NULL, 0, 0, NULL, NULL, NULL, 0, &hProcessHandle );
    if ( eError != osl_Process_E_None )
        return false;

    m_pProcessWait.reset( new ProcessTerminationWait( hProcessHandle, m_aAsyncFinishCallback ) );
    m_pProcessWait->create();
    return true;
}

//-------------------------------------------------------------------------
bool OOdbcManagement::isRunning() const
{
    return ( m_pProcessWait.get() && m_pProcessWait->isRunning() );
}

#endif // HAVE_ODBC_ADMINISTRATION

//.........................................................................
}   // namespace dbaui
//.........................................................................
<|endoftext|>