<commit_before>#pragma once

#include <sdbusplus/bus.hpp>
#include <sdbusplus/sdbus.hpp>

#include <type_traits>

namespace sdbusplus
{

namespace server
{

namespace object
{

// Forward declaration.
template <class... Args>
struct object;

namespace details
{

// Forward declaration.
template <class... Args>
struct compose;

/** Template to identify if an inheritance is a "normal" type or a nested
 *  sdbusplus::object.
 */
template <class T>
struct compose_inherit
{
    // This is a normal type.
    using type = T;

    // Normal types need emit_added called, if possible.
    template <class S>
    static void maybe_emit_iface_added(S* obj)
    {
        if constexpr (has_emit_added<S>())
        {
            obj->S::emit_added();
        }
    }

    // Test if emit_added() exists in T return std::true_type.
    template <class S>
    static constexpr auto has_emit_added_helper(int)
        -> decltype(std::declval<S>().emit_added(), std::true_type{});

    // If the above test fails, fall back to this to return std::false_type
    template <class>
    static constexpr std::false_type has_emit_added_helper(...);

    // Invoke the test with an int so it first resolves to
    // has_emit_added_helper(int), and when it fails, it resovles to
    // has_emit_added_helper(...) thanks to SFINAE.
    // So the return type is std::true_type if emit_added() exists in T and
    // std::false_type otherwise.
    template <class S>
    using has_emit_added = decltype(has_emit_added_helper<S>(0));
};

/** Template specialization for the sdbusplus::object nesting. */
template <class... Args>
struct compose_inherit<object<Args...>>
{
    // Unravel the inheritance with a recursive compose.
    using type = compose<Args...>;

    // Redirect the interface added to the composed parts.
    template <class T>
    static void maybe_emit_iface_added(T* obj)
    {
        obj->compose<Args...>::maybe_emit_iface_added();
    }
};

/** std-style _t alias for compose_inherit. */
template <class... Args>
using compose_inherit_t = typename compose_inherit<Args...>::type;

/** Templates to allow multiple inheritance via template parameters.
 *
 *  These allow an object to group multiple dbus interface bindings into a
 *  single class.
 */
template <class T, class... Rest>
struct compose_impl : compose_inherit_t<T>, compose_impl<Rest...>
{
    compose_impl(bus_t& bus, const char* path) :
        T(bus, path), compose_impl<Rest...>(bus, path)
    {}

    void maybe_emit_iface_added()
    {
        compose_inherit<T>::maybe_emit_iface_added(
            static_cast<compose_inherit_t<T>*>(this));
        compose_impl<Rest...>::maybe_emit_iface_added();
    }
};

/** Specialization for single element. */
template <class T>
struct compose_impl<T> : compose_inherit_t<T>
{
    compose_impl(bus_t& bus, const char* path) : compose_inherit_t<T>(bus, path)
    {}

    void maybe_emit_iface_added()
    {
        compose_inherit<T>::maybe_emit_iface_added(
            static_cast<compose_inherit_t<T>*>(this));
    }
};

/** Default compose operation for variadic arguments. */
template <class... Args>
struct compose : compose_impl<Args...>
{
    compose(bus_t& bus, const char* path) : compose_impl<Args...>(bus, path)
    {}

    friend struct compose_inherit<object<Args...>>;

  protected:
    void maybe_emit_iface_added()
    {
        compose_impl<Args...>::maybe_emit_iface_added();
    };
};

/** Specialization for zero variadic arguments. */
template <>
struct compose<>
{
    compose(bus_t& /*bus*/, const char* /*path*/)
    {}

  protected:
    void maybe_emit_iface_added(){};
};

} // namespace details

/** Class to compose multiple dbus interfaces and object signals.
 *
 *  Any number of classes representing a dbus interface may be composed into
 *  a single dbus object.  The interfaces will be created first and hooked
 *  into the object space via the 'add_object_vtable' calls.  Afterwards,
 *  a signal will be emitted for the whole object to indicate all new
 *  interfaces via 'sd_bus_emit_object_added'.
 *
 *  Similar, on destruction, the interfaces are removed (unref'd) and the
 *  'sd_bus_emit_object_removed' signals are emitted.
 *
 */
template <class... Args>
struct object :
    details::compose<Args...>,
    private sdbusplus::bus::details::bus_friend
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *         - Move operations.
     *     Allowed:
     *         - Destructor.
     */
    object() = delete;
    object(const object&) = delete;
    object& operator=(const object&) = delete;
    object(object&&) = delete;
    object& operator=(object&&) = delete;

    enum class action
    {
        /** sd_bus_emit_object_{added, removed} */
        emit_object_added,
        /** sd_bus_emit_interfaces_{added, removed} */
        emit_interface_added,
        /** no automatic added signal, but sd_bus_emit_object_removed on
         *  destruct */
        defer_emit,
        /** no interface signals */
        emit_no_signals,
    };

    /** Construct an 'object' on a bus with a path.
     *
     *  @param[in] bus - The bus to place the object on.
     *  @param[in] path - The path the object resides at.
     *  @param[in] act - Set to the desired InterfacesAdded signal behavior.
     */
    object(bus_t& bus, const char* path,
           action act = action::emit_object_added) :
        details::compose<Args...>(bus, path),
        __sdbusplus_server_object_bus(get_busp(bus), bus.getInterface()),
        __sdbusplus_server_object_path(path),
        __sdbusplus_server_object_intf(bus.getInterface())
    {
        // Default ctor
        check_action(act);
    }

    object(bus_t& bus, const char* path, bool deferSignal) :
        object(bus, path,
               deferSignal ? action::defer_emit : action::emit_object_added)
    {
        // Delegate to default ctor
    }

    ~object()
    {
        if (__sdbusplus_server_object_signalstate != action::emit_no_signals)
        {
            __sdbusplus_server_object_intf->sd_bus_emit_object_removed(
                get_busp(__sdbusplus_server_object_bus),
                __sdbusplus_server_object_path.c_str());
        }
    }

    /** Emit the 'object-added' signal, if not already sent. */
    void emit_object_added()
    {
        if (__sdbusplus_server_object_signalstate == action::defer_emit)
        {
            __sdbusplus_server_object_intf->sd_bus_emit_object_added(
                get_busp(__sdbusplus_server_object_bus),
                __sdbusplus_server_object_path.c_str());
            __sdbusplus_server_object_signalstate = action::emit_object_added;
        }
    }

  private:
    // These member names are purposefully chosen as long and, hopefully,
    // unique.  Since an object is 'composed' via multiple-inheritance,
    // all members need to have unique names to ensure there is no
    // ambiguity.
    bus_t __sdbusplus_server_object_bus;
    std::string __sdbusplus_server_object_path;
    action __sdbusplus_server_object_signalstate = action::defer_emit;
    SdBusInterface* __sdbusplus_server_object_intf;

    /** Check and run the action */
    void check_action(action act)
    {
        switch (act)
        {
            case action::emit_object_added:
                // We are wanting to call emit_object_added to set up in
                // deferred state temporarily and then emit the signal.
                __sdbusplus_server_object_signalstate = action::defer_emit;
                emit_object_added();
                break;

            case action::emit_interface_added:
                details::compose<Args...>::maybe_emit_iface_added();
                // If we are emitting at an interface level, we should never
                // also emit at the object level.
                __sdbusplus_server_object_signalstate = action::emit_no_signals;
                break;

            case action::defer_emit:
                __sdbusplus_server_object_signalstate = action::defer_emit;
                break;

            case action::emit_no_signals:
                __sdbusplus_server_object_signalstate = action::emit_no_signals;
                break;
        }
    }
};

} // namespace object

template <class... Args>
using object_t = object::object<Args...>;

} // namespace server
} // namespace sdbusplus
<commit_msg>server: object: remove non-enumerated ctor version<commit_after>#pragma once

#include <sdbusplus/bus.hpp>
#include <sdbusplus/sdbus.hpp>

#include <type_traits>

namespace sdbusplus
{

namespace server
{

namespace object
{

// Forward declaration.
template <class... Args>
struct object;

namespace details
{

// Forward declaration.
template <class... Args>
struct compose;

/** Template to identify if an inheritance is a "normal" type or a nested
 *  sdbusplus::object.
 */
template <class T>
struct compose_inherit
{
    // This is a normal type.
    using type = T;

    // Normal types need emit_added called, if possible.
    template <class S>
    static void maybe_emit_iface_added(S* obj)
    {
        if constexpr (has_emit_added<S>())
        {
            obj->S::emit_added();
        }
    }

    // Test if emit_added() exists in T return std::true_type.
    template <class S>
    static constexpr auto has_emit_added_helper(int)
        -> decltype(std::declval<S>().emit_added(), std::true_type{});

    // If the above test fails, fall back to this to return std::false_type
    template <class>
    static constexpr std::false_type has_emit_added_helper(...);

    // Invoke the test with an int so it first resolves to
    // has_emit_added_helper(int), and when it fails, it resovles to
    // has_emit_added_helper(...) thanks to SFINAE.
    // So the return type is std::true_type if emit_added() exists in T and
    // std::false_type otherwise.
    template <class S>
    using has_emit_added = decltype(has_emit_added_helper<S>(0));
};

/** Template specialization for the sdbusplus::object nesting. */
template <class... Args>
struct compose_inherit<object<Args...>>
{
    // Unravel the inheritance with a recursive compose.
    using type = compose<Args...>;

    // Redirect the interface added to the composed parts.
    template <class T>
    static void maybe_emit_iface_added(T* obj)
    {
        obj->compose<Args...>::maybe_emit_iface_added();
    }
};

/** std-style _t alias for compose_inherit. */
template <class... Args>
using compose_inherit_t = typename compose_inherit<Args...>::type;

/** Templates to allow multiple inheritance via template parameters.
 *
 *  These allow an object to group multiple dbus interface bindings into a
 *  single class.
 */
template <class T, class... Rest>
struct compose_impl : compose_inherit_t<T>, compose_impl<Rest...>
{
    compose_impl(bus_t& bus, const char* path) :
        T(bus, path), compose_impl<Rest...>(bus, path)
    {}

    void maybe_emit_iface_added()
    {
        compose_inherit<T>::maybe_emit_iface_added(
            static_cast<compose_inherit_t<T>*>(this));
        compose_impl<Rest...>::maybe_emit_iface_added();
    }
};

/** Specialization for single element. */
template <class T>
struct compose_impl<T> : compose_inherit_t<T>
{
    compose_impl(bus_t& bus, const char* path) : compose_inherit_t<T>(bus, path)
    {}

    void maybe_emit_iface_added()
    {
        compose_inherit<T>::maybe_emit_iface_added(
            static_cast<compose_inherit_t<T>*>(this));
    }
};

/** Default compose operation for variadic arguments. */
template <class... Args>
struct compose : compose_impl<Args...>
{
    compose(bus_t& bus, const char* path) : compose_impl<Args...>(bus, path)
    {}

    friend struct compose_inherit<object<Args...>>;

  protected:
    void maybe_emit_iface_added()
    {
        compose_impl<Args...>::maybe_emit_iface_added();
    };
};

/** Specialization for zero variadic arguments. */
template <>
struct compose<>
{
    compose(bus_t& /*bus*/, const char* /*path*/)
    {}

  protected:
    void maybe_emit_iface_added(){};
};

} // namespace details

/** Class to compose multiple dbus interfaces and object signals.
 *
 *  Any number of classes representing a dbus interface may be composed into
 *  a single dbus object.  The interfaces will be created first and hooked
 *  into the object space via the 'add_object_vtable' calls.  Afterwards,
 *  a signal will be emitted for the whole object to indicate all new
 *  interfaces via 'sd_bus_emit_object_added'.
 *
 *  Similar, on destruction, the interfaces are removed (unref'd) and the
 *  'sd_bus_emit_object_removed' signals are emitted.
 *
 */
template <class... Args>
struct object :
    details::compose<Args...>,
    private sdbusplus::bus::details::bus_friend
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *         - Move operations.
     *     Allowed:
     *         - Destructor.
     */
    object() = delete;
    object(const object&) = delete;
    object& operator=(const object&) = delete;
    object(object&&) = delete;
    object& operator=(object&&) = delete;

    enum class action
    {
        /** sd_bus_emit_object_{added, removed} */
        emit_object_added,
        /** sd_bus_emit_interfaces_{added, removed} */
        emit_interface_added,
        /** no automatic added signal, but sd_bus_emit_object_removed on
         *  destruct */
        defer_emit,
        /** no interface signals */
        emit_no_signals,
    };

    /** Construct an 'object' on a bus with a path.
     *
     *  @param[in] bus - The bus to place the object on.
     *  @param[in] path - The path the object resides at.
     *  @param[in] act - Set to the desired InterfacesAdded signal behavior.
     */
    object(bus_t& bus, const char* path,
           action act = action::emit_object_added) :
        details::compose<Args...>(bus, path),
        __sdbusplus_server_object_bus(get_busp(bus), bus.getInterface()),
        __sdbusplus_server_object_path(path),
        __sdbusplus_server_object_intf(bus.getInterface())
    {
        // Default ctor
        check_action(act);
    }

    ~object()
    {
        if (__sdbusplus_server_object_signalstate != action::emit_no_signals)
        {
            __sdbusplus_server_object_intf->sd_bus_emit_object_removed(
                get_busp(__sdbusplus_server_object_bus),
                __sdbusplus_server_object_path.c_str());
        }
    }

    /** Emit the 'object-added' signal, if not already sent. */
    void emit_object_added()
    {
        if (__sdbusplus_server_object_signalstate == action::defer_emit)
        {
            __sdbusplus_server_object_intf->sd_bus_emit_object_added(
                get_busp(__sdbusplus_server_object_bus),
                __sdbusplus_server_object_path.c_str());
            __sdbusplus_server_object_signalstate = action::emit_object_added;
        }
    }

  private:
    // These member names are purposefully chosen as long and, hopefully,
    // unique.  Since an object is 'composed' via multiple-inheritance,
    // all members need to have unique names to ensure there is no
    // ambiguity.
    bus_t __sdbusplus_server_object_bus;
    std::string __sdbusplus_server_object_path;
    action __sdbusplus_server_object_signalstate = action::defer_emit;
    SdBusInterface* __sdbusplus_server_object_intf;

    /** Check and run the action */
    void check_action(action act)
    {
        switch (act)
        {
            case action::emit_object_added:
                // We are wanting to call emit_object_added to set up in
                // deferred state temporarily and then emit the signal.
                __sdbusplus_server_object_signalstate = action::defer_emit;
                emit_object_added();
                break;

            case action::emit_interface_added:
                details::compose<Args...>::maybe_emit_iface_added();
                // If we are emitting at an interface level, we should never
                // also emit at the object level.
                __sdbusplus_server_object_signalstate = action::emit_no_signals;
                break;

            case action::defer_emit:
                __sdbusplus_server_object_signalstate = action::defer_emit;
                break;

            case action::emit_no_signals:
                __sdbusplus_server_object_signalstate = action::emit_no_signals;
                break;
        }
    }
};

} // namespace object

template <class... Args>
using object_t = object::object<Args...>;

} // namespace server
} // namespace sdbusplus
<|endoftext|>


<commit_before>#pragma once

namespace the
{
namespace time
{

template < typename Clock >
class FrequencyMeter
{
  public:
    FrequencyMeter( const Clock& clock )
      : m_clock( clock )
      , m_last_tick( 0 )
      , m_last_interval( 0.0 )
    {
    }

    void tick()
    {
      const typename Clock::Time now( m_clock.now() );
      m_last_interval = now - m_last_tick;
      m_last_tick = now;
    }

    float per_second() const
    {
      return Clock::ticks_per_second * 1.0 / m_last_interval;
    }

    typename Clock::Time interval() const
    {
      return m_last_interval;
    }

  private:
    const Clock& m_clock;
    typename Clock::Time m_last_tick;
    typename Clock::Time m_last_interval;
};

}
}

<commit_msg>replace float with integral type initialization in frequency meter<commit_after>#pragma once

namespace the
{
namespace time
{

template < typename Clock >
class FrequencyMeter
{
  public:
    FrequencyMeter( const Clock& clock )
      : m_clock( clock )
      , m_last_tick( 0 )
      , m_last_interval( 0 )
    {
    }

    void tick()
    {
      const typename Clock::Time now( m_clock.now() );
      m_last_interval = now - m_last_tick;
      m_last_tick = now;
    }

    float per_second() const
    {
      return Clock::ticks_per_second * 1.0 / m_last_interval;
    }

    typename Clock::Time interval() const
    {
      return m_last_interval;
    }

  private:
    const Clock& m_clock;
    typename Clock::Time m_last_tick;
    typename Clock::Time m_last_interval;
};

}
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "helpviewer.h"
#include "helpconstants.h"
#include "localhelpmanager.h"

#include <coreplugin/icore.h>

#include <utils/fileutils.h>

#include <QFileInfo>
#include <QStringBuilder>
#include <QDir>
#include <QUrl>

#include <QApplication>
#include <QDesktopServices>
#include <QMouseEvent>

#include <QHelpEngine>

using namespace Help::Internal;

struct ExtensionMap {
    const char *extension;
    const char *mimeType;
} extensionMap[] = {
    { ".bmp", "image/bmp" },
    { ".css", "text/css" },
    { ".gif", "image/gif" },
    { ".html", "text/html" },
    { ".htm", "text/html" },
    { ".ico", "image/x-icon" },
    { ".jpeg", "image/jpeg" },
    { ".jpg", "image/jpeg" },
    { ".js", "application/x-javascript" },
    { ".mng", "video/x-mng" },
    { ".pbm", "image/x-portable-bitmap" },
    { ".pgm", "image/x-portable-graymap" },
    { ".pdf", "application/pdf" },
    { ".png", "image/png" },
    { ".ppm", "image/x-portable-pixmap" },
    { ".rss", "application/rss+xml" },
    { ".svg", "image/svg+xml" },
    { ".svgz", "image/svg+xml" },
    { ".text", "text/plain" },
    { ".tif", "image/tiff" },
    { ".tiff", "image/tiff" },
    { ".txt", "text/plain" },
    { ".xbm", "image/x-xbitmap" },
    { ".xml", "text/xml" },
    { ".xpm", "image/x-xpm" },
    { ".xsl", "text/xsl" },
    { ".xhtml", "application/xhtml+xml" },
    { ".wml", "text/vnd.wap.wml" },
    { ".wmlc", "application/vnd.wap.wmlc" },
    { "about:blank", 0 },
    { 0, 0 }
};

bool HelpViewer::isLocalUrl(const QUrl &url)
{
    return url.scheme() == QLatin1String("qthelp");
}

bool HelpViewer::canOpenPage(const QString &url)
{
    return !mimeFromUrl(url).isEmpty();
}

QString HelpViewer::mimeFromUrl(const QUrl &url)
{
    const QString &path = url.path();
    const int index = path.lastIndexOf(QLatin1Char('.'));
    const QByteArray &ext = path.mid(index).toUtf8().toLower();

    const ExtensionMap *e = extensionMap;
    while (e->extension) {
        if (ext == e->extension)
            return QLatin1String(e->mimeType);
        ++e;
    }
    return QLatin1String("");
}

bool HelpViewer::launchWithExternalApp(const QUrl &url)
{
    if (isLocalUrl(url)) {
        const QHelpEngineCore &helpEngine = LocalHelpManager::helpEngine();
        const QUrl &resolvedUrl = helpEngine.findFile(url);
        if (!resolvedUrl.isValid())
            return false;

        const QString& path = resolvedUrl.path();
        if (!canOpenPage(path)) {
            Utils::TempFileSaver saver(QDir::tempPath()
                + QLatin1String("/qtchelp_XXXXXX.") + QFileInfo(path).completeSuffix());
            saver.setAutoRemove(false);
            if (!saver.hasError())
                saver.write(helpEngine.fileData(resolvedUrl));
            if (saver.finalize(Core::ICore::mainWindow()))
                QDesktopServices::openUrl(QUrl(saver.fileName()));
            return true;
        }
        return false;
    }
    QDesktopServices::openUrl(url);
    return true;
}

void HelpViewer::home()
{
    const QHelpEngineCore &engine = LocalHelpManager::helpEngine();
    QString homepage = engine.customValue(QLatin1String("HomePage"),
        QLatin1String("")).toString();

    if (homepage.isEmpty()) {
        homepage = engine.customValue(QLatin1String("DefaultHomePage"),
            Help::Constants::AboutBlank).toString();
    }

    setSource(homepage);
}

void HelpViewer::slotLoadStarted()
{
    qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
}

void HelpViewer::slotLoadFinished(bool ok)
{
    Q_UNUSED(ok)
    emit sourceChanged(source());
    qApp->restoreOverrideCursor();
}

bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *event)
{
    if (event->button() == Qt::XButton1) {
        backward();
        return true;
    }
    if (event->button() == Qt::XButton2) {
        forward();
        return true;
    }

    return false;
}
<commit_msg>Help: avoid opening external browser for 'no documentation available'<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "helpviewer.h"
#include "helpconstants.h"
#include "localhelpmanager.h"

#include <coreplugin/icore.h>

#include <utils/fileutils.h>

#include <QFileInfo>
#include <QStringBuilder>
#include <QDir>
#include <QUrl>

#include <QApplication>
#include <QDesktopServices>
#include <QMouseEvent>

#include <QHelpEngine>

using namespace Help::Internal;

struct ExtensionMap {
    const char *extension;
    const char *mimeType;
} extensionMap[] = {
    { ".bmp", "image/bmp" },
    { ".css", "text/css" },
    { ".gif", "image/gif" },
    { ".html", "text/html" },
    { ".htm", "text/html" },
    { ".ico", "image/x-icon" },
    { ".jpeg", "image/jpeg" },
    { ".jpg", "image/jpeg" },
    { ".js", "application/x-javascript" },
    { ".mng", "video/x-mng" },
    { ".pbm", "image/x-portable-bitmap" },
    { ".pgm", "image/x-portable-graymap" },
    { ".pdf", "application/pdf" },
    { ".png", "image/png" },
    { ".ppm", "image/x-portable-pixmap" },
    { ".rss", "application/rss+xml" },
    { ".svg", "image/svg+xml" },
    { ".svgz", "image/svg+xml" },
    { ".text", "text/plain" },
    { ".tif", "image/tiff" },
    { ".tiff", "image/tiff" },
    { ".txt", "text/plain" },
    { ".xbm", "image/x-xbitmap" },
    { ".xml", "text/xml" },
    { ".xpm", "image/x-xpm" },
    { ".xsl", "text/xsl" },
    { ".xhtml", "application/xhtml+xml" },
    { ".wml", "text/vnd.wap.wml" },
    { ".wmlc", "application/vnd.wap.wmlc" },
    { "about:blank", 0 },
    { 0, 0 }
};

bool HelpViewer::isLocalUrl(const QUrl &url)
{
    return url.scheme() == QLatin1String("about") // "No documenation available"
            || url.scheme() == QLatin1String("qthelp");
}

bool HelpViewer::canOpenPage(const QString &url)
{
    return !mimeFromUrl(url).isEmpty();
}

QString HelpViewer::mimeFromUrl(const QUrl &url)
{
    const QString &path = url.path();
    const int index = path.lastIndexOf(QLatin1Char('.'));
    const QByteArray &ext = path.mid(index).toUtf8().toLower();

    const ExtensionMap *e = extensionMap;
    while (e->extension) {
        if (ext == e->extension)
            return QLatin1String(e->mimeType);
        ++e;
    }
    return QLatin1String("");
}

bool HelpViewer::launchWithExternalApp(const QUrl &url)
{
    if (isLocalUrl(url)) {
        const QHelpEngineCore &helpEngine = LocalHelpManager::helpEngine();
        const QUrl &resolvedUrl = helpEngine.findFile(url);
        if (!resolvedUrl.isValid())
            return false;

        const QString& path = resolvedUrl.path();
        if (!canOpenPage(path)) {
            Utils::TempFileSaver saver(QDir::tempPath()
                + QLatin1String("/qtchelp_XXXXXX.") + QFileInfo(path).completeSuffix());
            saver.setAutoRemove(false);
            if (!saver.hasError())
                saver.write(helpEngine.fileData(resolvedUrl));
            if (saver.finalize(Core::ICore::mainWindow()))
                QDesktopServices::openUrl(QUrl(saver.fileName()));
            return true;
        }
        return false;
    }
    QDesktopServices::openUrl(url);
    return true;
}

void HelpViewer::home()
{
    const QHelpEngineCore &engine = LocalHelpManager::helpEngine();
    QString homepage = engine.customValue(QLatin1String("HomePage"),
        QLatin1String("")).toString();

    if (homepage.isEmpty()) {
        homepage = engine.customValue(QLatin1String("DefaultHomePage"),
            Help::Constants::AboutBlank).toString();
    }

    setSource(homepage);
}

void HelpViewer::slotLoadStarted()
{
    qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
}

void HelpViewer::slotLoadFinished(bool ok)
{
    Q_UNUSED(ok)
    emit sourceChanged(source());
    qApp->restoreOverrideCursor();
}

bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *event)
{
    if (event->button() == Qt::XButton1) {
        backward();
        return true;
    }
    if (event->button() == Qt::XButton2) {
        forward();
        return true;
    }

    return false;
}
<|endoftext|>


<commit_before>#ifndef SILICIUM_REACTIVE_TUPLE_HPP
#define SILICIUM_REACTIVE_TUPLE_HPP

#include <silicium/observable/observer.hpp>
#include <silicium/config.hpp>
#include <bitset>

#if (defined(_MSC_VER) && (MSC_VER < 1900)) || !SILICIUM_COMPILER_HAS_USING || \
    SILICIUM_GCC47 /*GCC 4.7 crashes when using tuple*/
#define SILICIUM_RX_TUPLE_AVAILABLE 0
#else
#define SILICIUM_RX_TUPLE_AVAILABLE 1
#endif

#if SILICIUM_RX_TUPLE_AVAILABLE
#include <silicium/detail/integer_sequence.hpp>
#endif

namespace Si
{
#if SILICIUM_RX_TUPLE_AVAILABLE
	template <class... Parts>
	struct tuple_observable
	{
		typedef std::tuple<typename Parts::element_type...> element_type;
		typedef std::tuple<Parts...> parts_tuple;
		typedef element_type buffer_tuple;

		template <class PartsTuple>
		explicit tuple_observable(PartsTuple &&parts)
		    : parts(std::forward<PartsTuple>(parts))
		{
		}

#if !SILICIUM_COMPILER_GENERATES_MOVES
		tuple_observable(tuple_observable &&other)
		    : parts(std::move(other.parts))
		    , receiver(std::move(other.receiver))
		    , buffer(std::move(other.buffer))
		    , elements_received(std::move(other.elements_received))
		    , observers(std::move(other.observers))
		{
		}

		tuple_observable(tuple_observable const &other)
		    : parts(other.parts)
		    , receiver(other.receiver)
		    , buffer(other.buffer)
		    , elements_received(other.elements_received)
		    , observers(other.observers)
		{
		}

		tuple_observable &operator=(tuple_observable &&other)
		{
			parts = std::move(other.parts);
			receiver = std::move(other.receiver);
			buffer = std::move(other.buffer);
			elements_received = std::move(other.elements_received);
			observers = std::move(other.observers);
			return *this;
		}

		tuple_observable &operator=(tuple_observable const &other)
		{
			parts = other.parts;
			receiver = other.receiver;
			buffer = other.buffer;
			elements_received = other.elements_received;
			observers = other.observers;
			return *this;
		}
#endif

		void async_get_one(ptr_observer<observer<buffer_tuple>> receiver)
		{
			assert(!this->receiver);
			this->receiver = receiver.get();
			this->elements_received.reset();
			return async_get_one_impl<0, Parts...>();
		}

	private:
		template <class Element, std::size_t Index>
		struct tuple_observer : observer<Element>
		{
			tuple_observable *combinator = nullptr;

			virtual void got_element(Element value) SILICIUM_OVERRIDE
			{
				std::get<Index>(combinator->buffer) = std::move(value);
				combinator->elements_received.set(Index);
				combinator->check_received();
			}

			virtual void ended() SILICIUM_OVERRIDE
			{
				auto *receiver_copy = combinator->receiver;
				combinator->receiver = nullptr;
				receiver_copy->ended();
			}
		};

		template <class Indices>
		struct make_observers;

		template <std::size_t... I>
		struct make_observers<ranges::v3::integer_sequence<I...>>
		{
			typedef std::tuple<
			    tuple_observer<typename Parts::element_type, I>...> type;
		};

		typedef
		    typename make_observers<typename ranges::v3::make_integer_sequence<
		        sizeof...(Parts)>::type>::type observers_type;

		parts_tuple parts;
		observer<buffer_tuple> *receiver = nullptr;
		buffer_tuple buffer;
		std::bitset<sizeof...(Parts)> elements_received;
		observers_type observers;

		template <std::size_t Index, class Head, class... Tail>
		void async_get_one_impl()
		{
			auto &observer = std::get<Index>(observers);
			observer.combinator = this;
			auto &part = std::get<Index>(parts);
			part.async_get_one(observe_by_ref(observer));
			return async_get_one_impl<Index + 1, Tail...>();
		}

		template <std::size_t Index>
		void async_get_one_impl()
		{
		}

		void check_received()
		{
			if (!elements_received.all())
			{
				return;
			}

			auto *receiver_copy = receiver;
			receiver = nullptr;
			receiver_copy->got_element(std::move(buffer));
		}
	};

	template <class... Parts>
	auto make_tuple(Parts &&... parts)
#if !SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE
	    -> tuple_observable<typename std::decay<Parts>::type...>
#endif
	{
		return tuple_observable<typename std::decay<Parts>::type...>(
		    std::make_tuple(std::forward<Parts>(parts)...));
	}
#endif
}

#endif
<commit_msg>add missing #include<commit_after>#ifndef SILICIUM_REACTIVE_TUPLE_HPP
#define SILICIUM_REACTIVE_TUPLE_HPP

#include <silicium/observable/observer.hpp>
#include <silicium/config.hpp>
#include <bitset>
#include <tuple>

#if (defined(_MSC_VER) && (MSC_VER < 1900)) || !SILICIUM_COMPILER_HAS_USING || \
    SILICIUM_GCC47 /*GCC 4.7 crashes when using tuple*/
#define SILICIUM_RX_TUPLE_AVAILABLE 0
#else
#define SILICIUM_RX_TUPLE_AVAILABLE 1
#endif

#if SILICIUM_RX_TUPLE_AVAILABLE
#include <silicium/detail/integer_sequence.hpp>
#endif

namespace Si
{
#if SILICIUM_RX_TUPLE_AVAILABLE
	template <class... Parts>
	struct tuple_observable
	{
		typedef std::tuple<typename Parts::element_type...> element_type;
		typedef std::tuple<Parts...> parts_tuple;
		typedef element_type buffer_tuple;

		template <class PartsTuple>
		explicit tuple_observable(PartsTuple &&parts)
		    : parts(std::forward<PartsTuple>(parts))
		{
		}

#if !SILICIUM_COMPILER_GENERATES_MOVES
		tuple_observable(tuple_observable &&other)
		    : parts(std::move(other.parts))
		    , receiver(std::move(other.receiver))
		    , buffer(std::move(other.buffer))
		    , elements_received(std::move(other.elements_received))
		    , observers(std::move(other.observers))
		{
		}

		tuple_observable(tuple_observable const &other)
		    : parts(other.parts)
		    , receiver(other.receiver)
		    , buffer(other.buffer)
		    , elements_received(other.elements_received)
		    , observers(other.observers)
		{
		}

		tuple_observable &operator=(tuple_observable &&other)
		{
			parts = std::move(other.parts);
			receiver = std::move(other.receiver);
			buffer = std::move(other.buffer);
			elements_received = std::move(other.elements_received);
			observers = std::move(other.observers);
			return *this;
		}

		tuple_observable &operator=(tuple_observable const &other)
		{
			parts = other.parts;
			receiver = other.receiver;
			buffer = other.buffer;
			elements_received = other.elements_received;
			observers = other.observers;
			return *this;
		}
#endif

		void async_get_one(ptr_observer<observer<buffer_tuple>> receiver)
		{
			assert(!this->receiver);
			this->receiver = receiver.get();
			this->elements_received.reset();
			return async_get_one_impl<0, Parts...>();
		}

	private:
		template <class Element, std::size_t Index>
		struct tuple_observer : observer<Element>
		{
			tuple_observable *combinator = nullptr;

			virtual void got_element(Element value) SILICIUM_OVERRIDE
			{
				std::get<Index>(combinator->buffer) = std::move(value);
				combinator->elements_received.set(Index);
				combinator->check_received();
			}

			virtual void ended() SILICIUM_OVERRIDE
			{
				auto *receiver_copy = combinator->receiver;
				combinator->receiver = nullptr;
				receiver_copy->ended();
			}
		};

		template <class Indices>
		struct make_observers;

		template <std::size_t... I>
		struct make_observers<ranges::v3::integer_sequence<I...>>
		{
			typedef std::tuple<
			    tuple_observer<typename Parts::element_type, I>...> type;
		};

		typedef
		    typename make_observers<typename ranges::v3::make_integer_sequence<
		        sizeof...(Parts)>::type>::type observers_type;

		parts_tuple parts;
		observer<buffer_tuple> *receiver = nullptr;
		buffer_tuple buffer;
		std::bitset<sizeof...(Parts)> elements_received;
		observers_type observers;

		template <std::size_t Index, class Head, class... Tail>
		void async_get_one_impl()
		{
			auto &observer = std::get<Index>(observers);
			observer.combinator = this;
			auto &part = std::get<Index>(parts);
			part.async_get_one(observe_by_ref(observer));
			return async_get_one_impl<Index + 1, Tail...>();
		}

		template <std::size_t Index>
		void async_get_one_impl()
		{
		}

		void check_received()
		{
			if (!elements_received.all())
			{
				return;
			}

			auto *receiver_copy = receiver;
			receiver = nullptr;
			receiver_copy->got_element(std::move(buffer));
		}
	};

	template <class... Parts>
	auto make_tuple(Parts &&... parts)
#if !SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE
	    -> tuple_observable<typename std::decay<Parts>::type...>
#endif
	{
		return tuple_observable<typename std::decay<Parts>::type...>(
		    std::make_tuple(std::forward<Parts>(parts)...));
	}
#endif
}

#endif
<|endoftext|>


<commit_before>// jpgfactory.cxx -- jpeg frontend for TR library
//
// Written by Norman Vine, started August 2001.
//
// Copyright (C) 2001  Norman Vine - nhv@yahoo.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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#ifdef HAVE_WINDOWS_H
#  include <windows.h>
#endif

#include "jpgfactory.hxx"

#ifdef __cplusplus
extern "C" {
#endif

static void init_destination (j_compress_ptr cinfo);
static void term_destination (j_compress_ptr cinfo);
static boolean empty_output_buffer (j_compress_ptr cinfo);

#ifdef __cplusplus
}
#endif

// OSGFIME: offscreenrendering on osg - completely new context ...

typedef struct {
    struct jpeg_destination_mgr pub; /* public fields */
    unsigned char * outfile; /* target stream */
    JOCTET * buffer;         /* start of buffer */
    int numbytes;            /* num bytes used */
    int maxsize;             /* size of outfile */
    int error;               /* error flag */
} my_destination_mgr;

typedef my_destination_mgr * my_dest_ptr;

void (*jpgRenderFrame)(void) = NULL;

trJpgFactory::trJpgFactory() {
    imageWidth = imageHeight = 0;
    tile       = NULL;
    buffer     = NULL;
    IMAGE      = NULL;
    tr         = NULL;
    cinfo.dest = NULL;
}

trJpgFactory::~trJpgFactory() {
    destroy();
}

/*
 * deallocate our dynamic parts
 */

void trJpgFactory::destroy( int error )
{
    if( error )
        printf( "!! Malloc Failure trJpgFactory ( %d )!!\n",
                error );

    if( cinfo.dest )  jpeg_destroy_compress(&cinfo);
    if( tr )          trDelete(tr);
    if( IMAGE )       delete [] IMAGE;
    if( buffer )      delete [] buffer;
    if( tile )        delete [] tile;
}

/*
 * allocate and initialize the jpeg compress struct
 * application needs to dealocate this
 */

int trJpgFactory::jpeg_init()
{
    j_compress_ptr cinfoPtr = &cinfo;

    cinfoPtr->err = jpeg_std_error(&jerr);
    jpeg_create_compress(cinfoPtr);

    /* following taken from jpeg library exaample code */
    cinfoPtr->dest = (struct jpeg_destination_mgr *)
                     (*cinfoPtr->mem->alloc_small)
                     ((j_common_ptr)cinfoPtr,
                      JPOOL_PERMANENT,
                      sizeof(my_destination_mgr));

    my_dest_ptr dest = (my_dest_ptr)cinfoPtr->dest;

    if( !dest ) {
        destroy(5);
        return 5;
    }

    dest->pub.init_destination    = init_destination;
    dest->pub.empty_output_buffer = empty_output_buffer;
    dest->pub.term_destination    = term_destination;
    dest->outfile  = NULL;
    dest->numbytes = 0;
    dest->maxsize  = 0;

    cinfoPtr->image_width      = imageWidth;
    cinfoPtr->image_height     = imageHeight;
    cinfoPtr->input_components = 3;
    cinfoPtr->in_color_space   = JCS_RGB;
    jpeg_set_defaults(cinfoPtr);
    jpeg_set_quality(cinfoPtr, (100 * 90) >> 8, TRUE);

    return 0;
}

/*
 * may also be used as reinit() to change image size
 */

int trJpgFactory::init(int width, int height )
{
    destroy();

    if( width <= 0 || height <= 0 ) {
        imageWidth  = DEFAULT_XS;
        imageHeight = DEFAULT_YS;
    } else {
        imageWidth  = width;
        imageHeight = height;
    }

    int bufsize = imageWidth * imageHeight * 3 * sizeof(GLubyte);

    /* allocate buffer large enough to store one tile */
    tile = new GLubyte[bufsize];
    if (!tile) {
        destroy(1);
        return 1;
    }

    /* allocate buffer to hold a row of tiles */
    buffer = new GLubyte[ bufsize ];
    if (!buffer) {
        destroy(2);
        return 2;
    }

    /* this should be big enough */
    IMAGESIZE = bufsize + 1024;
    IMAGE = new unsigned char[ IMAGESIZE ];
    if( !IMAGE ) {
        destroy(3);
        return 3;
    }

    tr = trNew();
    if( !tr ) {
        destroy(4);
        return 4;
    }

    trRowOrder(tr, TR_TOP_TO_BOTTOM);
    trTileSize(tr, imageWidth, imageHeight, 0);
    trImageSize(tr, imageWidth, imageHeight);
    trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);

    return jpeg_init();
}

/*
 *compress the image
 */

int trJpgFactory::compress()
{
    JSAMPROW  row_pointer[1];
    int       row_stride;

    /* to keep track of jpeg library routines */
    my_dest_ptr dest = (my_dest_ptr) cinfo.dest;

    //printf("\tjpeg_start_compress(&cinfo, TRUE)\n");
    jpeg_start_compress(&cinfo, TRUE);
    if( !dest->error ) {
        dest->outfile = IMAGE;
        dest->maxsize = IMAGESIZE;
        row_stride    = cinfo.image_width * 3;

        while( cinfo.next_scanline < cinfo.image_height &&
               !dest->error )
        {
            row_pointer[0] = buffer + (cinfo.next_scanline * row_stride);
            jpeg_write_scanlines(&cinfo, row_pointer, 1);
        }
    }
    if( !dest->error ) {
        // printf("\n\tBEFORE: jpeg_finish_compress(&cinfo)\n");
        jpeg_finish_compress(&cinfo);
        // printf("\tAFTER: jpeg_finish_compress(&cinfo)\n");
    } else {
        printf("INTERNAL JPEG_FACTORY ERROR\n");
        jpeg_abort_compress(&cinfo);
        /* OK - I am paranoid */
        dest->numbytes = 0;
    }
    return dest->numbytes;
}

/*
 * Makes the image then calls compress()
 */

int trJpgFactory::render()
{
    if( !tr || !jpgRenderFrame ) {
        printf("!! NO tr !!\n   trJpgFactory::render()\n");
        return 0;
    }

    // Make sure we have SSG projection primed for current view
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* just to be safe... */
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // printf("\ttrBeginTile(tr)\n");
    trBeginTile(tr);
    jpgRenderFrame();
    trEndTile(tr);

    /* just to be safe */
    int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
    int curTileWidth  = trGet(tr, TR_CURRENT_TILE_WIDTH);

    /* reverse image top to bottom */
    int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
    int bytesPerTileRow  = imageWidth * 3*sizeof(GLubyte);
    int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
    int i;
    for (i=0;i<imageHeight;i++) {
        memcpy(buffer + (curTileHeight-1-i) * bytesPerImageRow, /* Dest */
               tile + i*bytesPerTileRow,              /* Src */
               bytesPerCurrentTileRow);               /* Byte count*/
    }

    //  printf("exit trJpgFactory::render()\n");
    return  compress();
}

#define OUTPUT_BUF_SIZE  4096

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Initialize destination --- called by jpeg_start_compress
 * before any data is actually written.
 */

static void init_destination (j_compress_ptr cinfo)
{
    // printf("enter init_destination()\n");
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    /* following taken from jpeg library exaample code
     * Allocate the output buffer ---
     * it automaically will be released when done with image */

    dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small)
                   ((j_common_ptr)cinfo, JPOOL_IMAGE,
                    OUTPUT_BUF_SIZE * sizeof(JOCTET) );

    if( !dest->buffer ) {
        printf("MALLOC FAILED jpegFactory init_destination()\n");
        dest->error = TRUE;
    } else {
        dest->error = FALSE;
    }
    dest->pub.next_output_byte = dest->buffer;
    dest->pub.free_in_buffer   = OUTPUT_BUF_SIZE;
    dest->numbytes = 0;
}

/*
 * Empty the output buffer --- called whenever buffer fills up.
 */

static boolean empty_output_buffer (j_compress_ptr cinfo)
{
    // printf("enter empty_output_buffer(%d)\n", OUTPUT_BUF_SIZE);
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    if( (!dest->error) &&
          ((dest->numbytes + OUTPUT_BUF_SIZE) < dest->maxsize) )
    {
        memcpy( dest->outfile+dest->numbytes, dest->buffer, (size_t)OUTPUT_BUF_SIZE);

        dest->pub.next_output_byte = dest->buffer;
        dest->pub.free_in_buffer   = OUTPUT_BUF_SIZE;

        dest->numbytes += OUTPUT_BUF_SIZE;
    } else {
        printf("BUFFER OVERFLOW jpegFactory empty_output_buffer()\n");
        dest->numbytes = 0;
        dest->error    = TRUE;
    }
    return TRUE;
}

/*
 * Terminate destination --- called by jpeg_finish_compress
 * after all data has been written.  Usually needs to flush buffer.
 *
 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
 * application must deal with any cleanup that should happen even
 * for error exit.
 */

static void term_destination (j_compress_ptr cinfo)
{
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;

    if( (!dest->error) &&
          ((dest->numbytes + datacount) < (unsigned int)dest->maxsize) )
    {
        memcpy( dest->outfile+dest->numbytes, dest->buffer, datacount);
        dest->numbytes += datacount;
    } else {
        printf("BUFFER OVERFLOW jpegFactory term_destination()\n");
        dest->numbytes = 0;
        dest->error = TRUE;
    }
    // printf(" term_destination(%d) total %d\n", datacount, dest->numbytes );
}

#ifdef __cplusplus
}
#endif

<commit_msg>memcpy needs #include <string.h><commit_after>// jpgfactory.cxx -- jpeg frontend for TR library
//
// Written by Norman Vine, started August 2001.
//
// Copyright (C) 2001  Norman Vine - nhv@yahoo.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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#ifdef HAVE_WINDOWS_H
#  include <windows.h>
#endif

#include "jpgfactory.hxx"
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

static void init_destination (j_compress_ptr cinfo);
static void term_destination (j_compress_ptr cinfo);
static boolean empty_output_buffer (j_compress_ptr cinfo);

#ifdef __cplusplus
}
#endif

// OSGFIME: offscreenrendering on osg - completely new context ...

typedef struct {
    struct jpeg_destination_mgr pub; /* public fields */
    unsigned char * outfile; /* target stream */
    JOCTET * buffer;         /* start of buffer */
    int numbytes;            /* num bytes used */
    int maxsize;             /* size of outfile */
    int error;               /* error flag */
} my_destination_mgr;

typedef my_destination_mgr * my_dest_ptr;

void (*jpgRenderFrame)(void) = NULL;

trJpgFactory::trJpgFactory() {
    imageWidth = imageHeight = 0;
    tile       = NULL;
    buffer     = NULL;
    IMAGE      = NULL;
    tr         = NULL;
    cinfo.dest = NULL;
}

trJpgFactory::~trJpgFactory() {
    destroy();
}

/*
 * deallocate our dynamic parts
 */

void trJpgFactory::destroy( int error )
{
    if( error )
        printf( "!! Malloc Failure trJpgFactory ( %d )!!\n",
                error );

    if( cinfo.dest )  jpeg_destroy_compress(&cinfo);
    if( tr )          trDelete(tr);
    if( IMAGE )       delete [] IMAGE;
    if( buffer )      delete [] buffer;
    if( tile )        delete [] tile;
}

/*
 * allocate and initialize the jpeg compress struct
 * application needs to dealocate this
 */

int trJpgFactory::jpeg_init()
{
    j_compress_ptr cinfoPtr = &cinfo;

    cinfoPtr->err = jpeg_std_error(&jerr);
    jpeg_create_compress(cinfoPtr);

    /* following taken from jpeg library exaample code */
    cinfoPtr->dest = (struct jpeg_destination_mgr *)
                     (*cinfoPtr->mem->alloc_small)
                     ((j_common_ptr)cinfoPtr,
                      JPOOL_PERMANENT,
                      sizeof(my_destination_mgr));

    my_dest_ptr dest = (my_dest_ptr)cinfoPtr->dest;

    if( !dest ) {
        destroy(5);
        return 5;
    }

    dest->pub.init_destination    = init_destination;
    dest->pub.empty_output_buffer = empty_output_buffer;
    dest->pub.term_destination    = term_destination;
    dest->outfile  = NULL;
    dest->numbytes = 0;
    dest->maxsize  = 0;

    cinfoPtr->image_width      = imageWidth;
    cinfoPtr->image_height     = imageHeight;
    cinfoPtr->input_components = 3;
    cinfoPtr->in_color_space   = JCS_RGB;
    jpeg_set_defaults(cinfoPtr);
    jpeg_set_quality(cinfoPtr, (100 * 90) >> 8, TRUE);

    return 0;
}

/*
 * may also be used as reinit() to change image size
 */

int trJpgFactory::init(int width, int height )
{
    destroy();

    if( width <= 0 || height <= 0 ) {
        imageWidth  = DEFAULT_XS;
        imageHeight = DEFAULT_YS;
    } else {
        imageWidth  = width;
        imageHeight = height;
    }

    int bufsize = imageWidth * imageHeight * 3 * sizeof(GLubyte);

    /* allocate buffer large enough to store one tile */
    tile = new GLubyte[bufsize];
    if (!tile) {
        destroy(1);
        return 1;
    }

    /* allocate buffer to hold a row of tiles */
    buffer = new GLubyte[ bufsize ];
    if (!buffer) {
        destroy(2);
        return 2;
    }

    /* this should be big enough */
    IMAGESIZE = bufsize + 1024;
    IMAGE = new unsigned char[ IMAGESIZE ];
    if( !IMAGE ) {
        destroy(3);
        return 3;
    }

    tr = trNew();
    if( !tr ) {
        destroy(4);
        return 4;
    }

    trRowOrder(tr, TR_TOP_TO_BOTTOM);
    trTileSize(tr, imageWidth, imageHeight, 0);
    trImageSize(tr, imageWidth, imageHeight);
    trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);

    return jpeg_init();
}

/*
 *compress the image
 */

int trJpgFactory::compress()
{
    JSAMPROW  row_pointer[1];
    int       row_stride;

    /* to keep track of jpeg library routines */
    my_dest_ptr dest = (my_dest_ptr) cinfo.dest;

    //printf("\tjpeg_start_compress(&cinfo, TRUE)\n");
    jpeg_start_compress(&cinfo, TRUE);
    if( !dest->error ) {
        dest->outfile = IMAGE;
        dest->maxsize = IMAGESIZE;
        row_stride    = cinfo.image_width * 3;

        while( cinfo.next_scanline < cinfo.image_height &&
               !dest->error )
        {
            row_pointer[0] = buffer + (cinfo.next_scanline * row_stride);
            jpeg_write_scanlines(&cinfo, row_pointer, 1);
        }
    }
    if( !dest->error ) {
        // printf("\n\tBEFORE: jpeg_finish_compress(&cinfo)\n");
        jpeg_finish_compress(&cinfo);
        // printf("\tAFTER: jpeg_finish_compress(&cinfo)\n");
    } else {
        printf("INTERNAL JPEG_FACTORY ERROR\n");
        jpeg_abort_compress(&cinfo);
        /* OK - I am paranoid */
        dest->numbytes = 0;
    }
    return dest->numbytes;
}

/*
 * Makes the image then calls compress()
 */

int trJpgFactory::render()
{
    if( !tr || !jpgRenderFrame ) {
        printf("!! NO tr !!\n   trJpgFactory::render()\n");
        return 0;
    }

    // Make sure we have SSG projection primed for current view
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* just to be safe... */
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // printf("\ttrBeginTile(tr)\n");
    trBeginTile(tr);
    jpgRenderFrame();
    trEndTile(tr);

    /* just to be safe */
    int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
    int curTileWidth  = trGet(tr, TR_CURRENT_TILE_WIDTH);

    /* reverse image top to bottom */
    int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
    int bytesPerTileRow  = imageWidth * 3*sizeof(GLubyte);
    int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
    int i;
    for (i=0;i<imageHeight;i++) {
        memcpy(buffer + (curTileHeight-1-i) * bytesPerImageRow, /* Dest */
               tile + i*bytesPerTileRow,              /* Src */
               bytesPerCurrentTileRow);               /* Byte count*/
    }

    //  printf("exit trJpgFactory::render()\n");
    return  compress();
}

#define OUTPUT_BUF_SIZE  4096

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Initialize destination --- called by jpeg_start_compress
 * before any data is actually written.
 */

static void init_destination (j_compress_ptr cinfo)
{
    // printf("enter init_destination()\n");
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    /* following taken from jpeg library exaample code
     * Allocate the output buffer ---
     * it automaically will be released when done with image */

    dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small)
                   ((j_common_ptr)cinfo, JPOOL_IMAGE,
                    OUTPUT_BUF_SIZE * sizeof(JOCTET) );

    if( !dest->buffer ) {
        printf("MALLOC FAILED jpegFactory init_destination()\n");
        dest->error = TRUE;
    } else {
        dest->error = FALSE;
    }
    dest->pub.next_output_byte = dest->buffer;
    dest->pub.free_in_buffer   = OUTPUT_BUF_SIZE;
    dest->numbytes = 0;
}

/*
 * Empty the output buffer --- called whenever buffer fills up.
 */

static boolean empty_output_buffer (j_compress_ptr cinfo)
{
    // printf("enter empty_output_buffer(%d)\n", OUTPUT_BUF_SIZE);
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    if( (!dest->error) &&
          ((dest->numbytes + OUTPUT_BUF_SIZE) < dest->maxsize) )
    {
        memcpy( dest->outfile+dest->numbytes, dest->buffer, (size_t)OUTPUT_BUF_SIZE);

        dest->pub.next_output_byte = dest->buffer;
        dest->pub.free_in_buffer   = OUTPUT_BUF_SIZE;

        dest->numbytes += OUTPUT_BUF_SIZE;
    } else {
        printf("BUFFER OVERFLOW jpegFactory empty_output_buffer()\n");
        dest->numbytes = 0;
        dest->error    = TRUE;
    }
    return TRUE;
}

/*
 * Terminate destination --- called by jpeg_finish_compress
 * after all data has been written.  Usually needs to flush buffer.
 *
 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
 * application must deal with any cleanup that should happen even
 * for error exit.
 */

static void term_destination (j_compress_ptr cinfo)
{
    my_dest_ptr dest = (my_dest_ptr) cinfo->dest;

    size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;

    if( (!dest->error) &&
          ((dest->numbytes + datacount) < (unsigned int)dest->maxsize) )
    {
        memcpy( dest->outfile+dest->numbytes, dest->buffer, datacount);
        dest->numbytes += datacount;
    } else {
        printf("BUFFER OVERFLOW jpegFactory term_destination()\n");
        dest->numbytes = 0;
        dest->error = TRUE;
    }
    // printf(" term_destination(%d) total %d\n", datacount, dest->numbytes );
}

#ifdef __cplusplus
}
#endif

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

#include "pybind11/pybind11.h"

#include <string>

#include "config/the_isa.hh"

#if THE_ISA != NULL_ISA
#include "dev/net/etherdevice.hh"
#include "dev/net/etherint.hh"
#include "dev/net/etherobject.hh"

#endif

#include "mem/mem_object.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "sim/full_system.hh"

namespace py = pybind11;

#if THE_ISA != NULL_ISA
static EtherInt *
lookupEthPort(SimObject *so, const std::string &name, int i)
{
    EtherObject *eo = dynamic_cast<EtherObject *>(so);
    EtherDevice *ed = dynamic_cast<EtherDevice *>(so);
    if (eo == NULL && ed == NULL) {
        warn("error casting SimObject %s", so->name());
        return NULL;
    }

    EtherInt *p = NULL;
    if (eo)
        p = eo->getEthPort(name, i);
    else
        p = ed->getEthPort(name, i);
    return p;
}
#endif

/**
 * Connect the described MemObject ports.  Called from Python.
 * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
 * SimObject1 is the master, and SimObject2 is the slave
 */
static int
connectPorts(SimObject *o1, const std::string &name1, int i1,
             SimObject *o2, const std::string &name2, int i2)
{
#if THE_ISA != NULL_ISA
    EtherObject *eo1, *eo2;
    EtherDevice *ed1, *ed2;
    eo1 = dynamic_cast<EtherObject*>(o1);
    ed1 = dynamic_cast<EtherDevice*>(o1);
    eo2 = dynamic_cast<EtherObject*>(o2);
    ed2 = dynamic_cast<EtherDevice*>(o2);

    if ((eo1 || ed1) && (eo2 || ed2)) {
        EtherInt *p1 = lookupEthPort(o1, name1, i1);
        EtherInt *p2 = lookupEthPort(o2, name2, i2);

        if (p1 != NULL &&  p2 != NULL) {

            p1->setPeer(p2);
            p2->setPeer(p1);

            return 1;
        }
    }
#endif

    // These could be MessageBuffers from the ruby memory system. If so, they
    // need not be connected to anything currently.
    MessageBuffer *mb1, *mb2;
    mb1 = dynamic_cast<MessageBuffer*>(o1);
    mb2 = dynamic_cast<MessageBuffer*>(o2);

    if (mb1 || mb2) {
        // No need to connect anything here currently. MessageBuffer
        // connections in Python only serve to print the connections in
        // the config output.
        // TODO: Add real ports to MessageBuffers and use MemObject connect
        // code below to bind MessageBuffer senders and receivers
        return 1;
    }

    MemObject *mo1, *mo2;
    mo1 = dynamic_cast<MemObject*>(o1);
    mo2 = dynamic_cast<MemObject*>(o2);

    if (mo1 == NULL || mo2 == NULL) {
        panic ("Error casting SimObjects %s and %s to MemObject", o1->name(),
               o2->name());
    }

    // generic master/slave port connection
    BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1);
    BaseSlavePort& slavePort   = mo2->getSlavePort(name2, i2);

    masterPort.bind(slavePort);

    return 1;
}

void
pybind_init_pyobject(py::module &m_native)
{
    py::module m = m_native.def_submodule("pyobject");

    m.def("connectPorts", &connectPorts);
}
<commit_msg>python: Stop conditionally excluding code from pyobject.cc<commit_after>/*
 * Copyright (c) 2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 */

#include "pybind11/pybind11.h"

#include <string>

#include "config/the_isa.hh"

#include "dev/net/etherdevice.hh"
#include "dev/net/etherint.hh"
#include "dev/net/etherobject.hh"
#include "mem/mem_object.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "sim/full_system.hh"

namespace py = pybind11;

static EtherInt *
lookupEthPort(SimObject *so, const std::string &name, int i)
{
    EtherObject *eo = dynamic_cast<EtherObject *>(so);
    EtherDevice *ed = dynamic_cast<EtherDevice *>(so);
    if (eo == NULL && ed == NULL) {
        warn("error casting SimObject %s", so->name());
        return NULL;
    }

    EtherInt *p = NULL;
    if (eo)
        p = eo->getEthPort(name, i);
    else
        p = ed->getEthPort(name, i);
    return p;
}

/**
 * Connect the described MemObject ports.  Called from Python.
 * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
 * SimObject1 is the master, and SimObject2 is the slave
 */
static int
connectPorts(SimObject *o1, const std::string &name1, int i1,
             SimObject *o2, const std::string &name2, int i2)
{
    EtherObject *eo1, *eo2;
    EtherDevice *ed1, *ed2;
    eo1 = dynamic_cast<EtherObject*>(o1);
    ed1 = dynamic_cast<EtherDevice*>(o1);
    eo2 = dynamic_cast<EtherObject*>(o2);
    ed2 = dynamic_cast<EtherDevice*>(o2);

    if ((eo1 || ed1) && (eo2 || ed2)) {
        EtherInt *p1 = lookupEthPort(o1, name1, i1);
        EtherInt *p2 = lookupEthPort(o2, name2, i2);

        if (p1 != NULL &&  p2 != NULL) {

            p1->setPeer(p2);
            p2->setPeer(p1);

            return 1;
        }
    }

    // These could be MessageBuffers from the ruby memory system. If so, they
    // need not be connected to anything currently.
    MessageBuffer *mb1, *mb2;
    mb1 = dynamic_cast<MessageBuffer*>(o1);
    mb2 = dynamic_cast<MessageBuffer*>(o2);

    if (mb1 || mb2) {
        // No need to connect anything here currently. MessageBuffer
        // connections in Python only serve to print the connections in
        // the config output.
        // TODO: Add real ports to MessageBuffers and use MemObject connect
        // code below to bind MessageBuffer senders and receivers
        return 1;
    }

    MemObject *mo1, *mo2;
    mo1 = dynamic_cast<MemObject*>(o1);
    mo2 = dynamic_cast<MemObject*>(o2);

    if (mo1 == NULL || mo2 == NULL) {
        panic ("Error casting SimObjects %s and %s to MemObject", o1->name(),
               o2->name());
    }

    // generic master/slave port connection
    BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1);
    BaseSlavePort& slavePort   = mo2->getSlavePort(name2, i2);

    masterPort.bind(slavePort);

    return 1;
}

void
pybind_init_pyobject(py::module &m_native)
{
    py::module m = m_native.def_submodule("pyobject");

    m.def("connectPorts", &connectPorts);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * ois_bind.cpp - bindings for OIS
 ******************************************************************************
 * This file is part of
 *     __ __              _
 *    / // /_____ ____   (_)
 *   / // // ___// __ \ / /
 *  / // // /__ / /_/ // /
 * /_//_/ \___/ \____//_/
 *
 * Low Level C Ogre Interface (llcoi)
 *
 * See http://code.google.com/p/llcoi/ for more information.
 *
 * Copyright (c) 2011, Llcoi Team
 *
 * License: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/
#include "ogre_interface.h"
#include "ois_interface.h"

#include <OISMouse.h>
#include <OISKeyboard.h>
#include <OISJoyStick.h>
#include <OISInputManager.h>

OIS::InputManager* input_manager = 0;

InputSystemHandle create_input_system(unsigned int window_handle)
{
	OIS::InputManager* input = OIS::InputManager::createInputSystem(window_handle);
    // XXX: Temporary until I get around to converting these functions
    // to not rely on global state of input_manager above.
    input_manager = input;

    return reinterpret_cast<InputSystemHandle>(input);
}

InputSystemHandle create_input_system_ex(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    OIS::InputManager* input = OIS::InputManager::createInputSystem(*paramlist);
    // XXX: Temporary until I get around to converting these functions
    // to not rely on global state of input_manager above.
    input_manager = input;
    return reinterpret_cast<InputSystemHandle>(input);
}

void destroy_input_system(InputSystemHandle handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::InputManager::destroyInputSystem(input);
    input_manager = 0;
}

MouseInputHandle create_mouse_object(int buffered)
{
	OIS::Mouse* mouse = static_cast<OIS::Mouse*>(input_manager->createInputObject( OIS::OISMouse, (bool)buffered ));
	return reinterpret_cast<MouseInputHandle>(mouse);
}

KeyboardInputHandle create_keyboard_object(int buffered)
{
    OIS::Keyboard* keyboard = static_cast<OIS::Keyboard*>(input_manager->createInputObject( OIS::OISKeyboard, (bool)buffered ));
	return reinterpret_cast<KeyboardInputHandle>(keyboard);
}

void destroy_mouse_object(MouseInputHandle mouse_handle)
{
	OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
	input_manager->destroyInputObject(mouse);
}

void destroy_keyboard_object(KeyboardInputHandle keyboard_handle)
{
	OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
	input_manager->destroyInputObject(keyboard);
}

int keyboard_is_key_down(KeyboardInputHandle keyboard_handle, enum KeyCode key_code)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isKeyDown((OIS::KeyCode)key_code))
        return 1;
    return 0;
}

int keyboard_is_modifier_down(KeyboardInputHandle keyboard_handle, Key_Modifier key_modifier)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isModifierDown((OIS::Keyboard::Modifier)key_modifier))
        return 1;
    return 0;
}

MouseState mouse_get_state(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    OIS::MouseState state = mouse->getMouseState();
    MouseState out_state;
    out_state.buttons = state.buttons;
    out_state.height = state.height;
    out_state.width = state.width;
    out_state.X.abs = state.X.abs;
    out_state.X.rel = state.X.rel;
    out_state.X.absOnly = state.X.absOnly;
    out_state.Y.abs = state.Y.abs;
    out_state.Y.rel = state.Y.rel;
    out_state.Y.absOnly = state.Y.absOnly;
    out_state.Z.abs = state.Z.abs;
    out_state.Z.rel = state.Z.rel;
    out_state.Z.absOnly = state.Z.absOnly;
    return out_state;
}

void mouse_set_buffered(MouseInputHandle mouse_handle, int buffered)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->setBuffered((bool)buffered);
}

void keyboard_set_buffered(KeyboardInputHandle keyboard_handle, int buffered)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->setBuffered((bool)buffered);
}

void keyboard_capture(KeyboardInputHandle keyboard_handle)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->capture();
}

void mouse_capture(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->capture();
}

ParamListHandle ois_create_paramlist()
{
    OIS::ParamList* paramlist = new OIS::ParamList;
    return reinterpret_cast<ParamListHandle>(paramlist);
}

void ois_destroy_paramlist(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    delete paramlist;
}

void ois_add_pair(ParamListHandle handle, const char* field, const char* value)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    paramlist->insert(
        std::make_pair(
            std::string(field), std::string(value)
        )
    );
}
<commit_msg>working on nuking global state<commit_after>/******************************************************************************
 * ois_bind.cpp - bindings for OIS
 ******************************************************************************
 * This file is part of
 *     __ __              _
 *    / // /_____ ____   (_)
 *   / // // ___// __ \ / /
 *  / // // /__ / /_/ // /
 * /_//_/ \___/ \____//_/
 *
 * Low Level C Ogre Interface (llcoi)
 *
 * See http://code.google.com/p/llcoi/ for more information.
 *
 * Copyright (c) 2011, Llcoi Team
 *
 * License: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/
#include "ogre_interface.h"
#include "ois_interface.h"

#include <OISMouse.h>
#include <OISKeyboard.h>
#include <OISJoyStick.h>
#include <OISInputManager.h>

InputSystemHandle create_input_system(unsigned int window_handle)
{
	OIS::InputManager* input = OIS::InputManager::createInputSystem(window_handle);
    return reinterpret_cast<InputSystemHandle>(input);
}

InputSystemHandle create_input_system_ex(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    OIS::InputManager* input = OIS::InputManager::createInputSystem(*paramlist);
    return reinterpret_cast<InputSystemHandle>(input);
}

void destroy_input_system(InputSystemHandle handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::InputManager::destroyInputSystem(input);
}

MouseInputHandle create_mouse_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = static_cast<OIS::Mouse*>(input->createInputObject( OIS::OISMouse, (bool)buffered ));
	return reinterpret_cast<MouseInputHandle>(mouse);
}

KeyboardInputHandle create_keyboard_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
    OIS::Keyboard* keyboard = static_cast<OIS::Keyboard*>(input->createInputObject( OIS::OISKeyboard, (bool)buffered ));
	return reinterpret_cast<KeyboardInputHandle>(keyboard);
}

void destroy_mouse_object(InputSystemHandle handle, MouseInputHandle mouse_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
	input->destroyInputObject(mouse);
}

void destroy_keyboard_object(InputSystemHandle handle, KeyboardInputHandle keyboard_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
	input->destroyInputObject(keyboard);
}

int keyboard_is_key_down(KeyboardInputHandle keyboard_handle, enum KeyCode key_code)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isKeyDown((OIS::KeyCode)key_code))
        return 1;
    return 0;
}

int keyboard_is_modifier_down(KeyboardInputHandle keyboard_handle, Key_Modifier key_modifier)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isModifierDown((OIS::Keyboard::Modifier)key_modifier))
        return 1;
    return 0;
}

MouseState mouse_get_state(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    OIS::MouseState state = mouse->getMouseState();
    MouseState out_state;
    out_state.buttons = state.buttons;
    out_state.height = state.height;
    out_state.width = state.width;
    out_state.X.abs = state.X.abs;
    out_state.X.rel = state.X.rel;
    out_state.X.absOnly = state.X.absOnly;
    out_state.Y.abs = state.Y.abs;
    out_state.Y.rel = state.Y.rel;
    out_state.Y.absOnly = state.Y.absOnly;
    out_state.Z.abs = state.Z.abs;
    out_state.Z.rel = state.Z.rel;
    out_state.Z.absOnly = state.Z.absOnly;
    return out_state;
}

void mouse_set_buffered(MouseInputHandle mouse_handle, int buffered)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->setBuffered((bool)buffered);
}

void keyboard_set_buffered(KeyboardInputHandle keyboard_handle, int buffered)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->setBuffered((bool)buffered);
}

void keyboard_capture(KeyboardInputHandle keyboard_handle)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->capture();
}

void mouse_capture(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->capture();
}

ParamListHandle ois_create_paramlist()
{
    OIS::ParamList* paramlist = new OIS::ParamList;
    return reinterpret_cast<ParamListHandle>(paramlist);
}

void ois_destroy_paramlist(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    delete paramlist;
}

void ois_add_pair(ParamListHandle handle, const char* field, const char* value)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    paramlist->insert(
        std::make_pair(
            std::string(field), std::string(value)
        )
    );
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// 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.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Context.h>
#include <Att.h>
#include <Task.h>
#include <test.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (20);

  // (blank)
  bool good = true;
  Task task;

  try {task = Task ("");}
  catch (std::string& e){t.diag (e); good = false;}
  t.notok (good, "Task::Task ('')");

  // []
  good = true;
  try {task = Task ("[]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.notok (good, "Task::Task ('[]')");

  // [name:value]
  good = true;
  try {task = Task ("[name:value]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[name:value]')");
  t.is (task.get ("name"), "value", "name=value");

  // [name:"value"]
  good = true;
  try {task = Task ("[name:\"value\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[name:\"value\"]')");
  t.is (task.get ("name"), "value", "name=value");

  // [name:"one two"]
  good = true;
  try {task = Task ("[name:\"one two\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[name:\"one two\"]')");
  t.is (task.get ("name"), "one two", "name=one two");

  // [one:two three:four]
  good = true;
  try {task = Task ("[one:\"two\" three:\"four\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[one:\"two\" three:\"four\"]')");
  t.is (task.get ("one"), "two", "one=two");
  t.is (task.get ("three"), "four", "three=four");

  // Task::set
  task.clear ();
  task.set ("name", "value");
  t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::set");

  // Task::has
  t.ok    (task.has ("name"), "Task::has");
  t.notok (task.has ("woof"), "Task::has not");

  // Task::get_int
  task.set ("one", 1);
  t.is (task.composeF4 (), "[name:\"value\" one:\"1\"]\n", "Task::set");
  t.is (task.get_int ("one"), 1, "Task::get_int");

  // Task::get_ulong
  task.set ("two", "4294967295");
  t.is (task.composeF4 (), "[name:\"value\" one:\"1\" two:\"4294967295\"]\n", "Task::set");
  t.is ((size_t)task.get_ulong ("two"), (size_t)4294967295, "Task::get_ulong");

  // Task::remove
  task.remove ("one");
  task.remove ("two");
  t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::remove");

  // Task::all
  t.is (task.size (), (size_t)1, "Task::all size");

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Unit Tests - t2.t<commit_after>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// 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.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Context.h>
#include <Att.h>
#include <Task.h>
#include <test.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (18);

  // (blank)
  bool good = true;
  Task task;

  try {task = Task ("");}
  catch (std::string& e){t.diag (e); good = false;}
  t.notok (good, "Task::Task ('')");

  // []
  good = true;
  try {task = Task ("[]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.notok (good, "Task::Task ('[]')");

  // [name:"value"]
  good = true;
  try {task = Task ("[name:\"value\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[name:\"value\"]')");
  t.is (task.get ("name"), "value", "name=value");

  // [name:"one two"]
  good = true;
  try {task = Task ("[name:\"one two\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[name:\"one two\"]')");
  t.is (task.get ("name"), "one two", "name=one two");

  // [one:two three:four]
  good = true;
  try {task = Task ("[one:\"two\" three:\"four\"]");}
  catch (std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('[one:\"two\" three:\"four\"]')");
  t.is (task.get ("one"), "two", "one=two");
  t.is (task.get ("three"), "four", "three=four");

  // Task::set
  task.clear ();
  task.set ("name", "value");
  t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::set");

  // Task::has
  t.ok    (task.has ("name"), "Task::has");
  t.notok (task.has ("woof"), "Task::has not");

  // Task::get_int
  task.set ("one", 1);
  t.is (task.composeF4 (), "[name:\"value\" one:\"1\"]\n", "Task::set");
  t.is (task.get_int ("one"), 1, "Task::get_int");

  // Task::get_ulong
  task.set ("two", "4294967295");
  t.is (task.composeF4 (), "[name:\"value\" one:\"1\" two:\"4294967295\"]\n", "Task::set");
  t.is ((size_t)task.get_ulong ("two"), (size_t)4294967295, "Task::get_ulong");

  // Task::remove
  task.remove ("one");
  task.remove ("two");
  t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::remove");

  // Task::all
  t.is (task.size (), (size_t)1, "Task::all size");

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>/**
 * Template C++ file.
 * Function with references to pointers: func(int *&ptr);
 */
/********************* Header Files ***********************/
/* C++ Headers */
#include <iostream> /* Input/output objects. */
//#include <fstream> /* File operations. */
//#include <sstream> /* String stream. */
#include <string> /* C++ String class. */
//#include <new> /* Defines bad_malloc exception, new functions. */
//#include <typeinfo> /* Casting header. */
//#include <exception> /* Top level exception header. */
//#include <stdexcept> /* Derived exception classes. */

/* STL Headers */
#include <vector>
//#include <list>
//#include <deque>
//#include <stack>
//#include <queue>
//#include <priority_queue>
//#include <bitset>
//#include <set> // multiset for multiple keys allowed.
//#include <map> // multimap for multiple keys allowed.
//#include <utility> // Has pair for map.
//#include <algorithm>
//#include <numeric>
//#include <functional> // Functional objects.
//#include <iterator> // Contains back_inserter function and like.

/* C Headers */
//#include <cstdlib>
//#include <cstddef>
//#include <cctype>
//#include <cstring>
//#include <cstdio>
//#include <climits>
//#include <cassert>

/* Project Headers */
#include "gtest/gtest.h"

/******************* Constants/Macros *********************/

/**************** Namespace Declarations ******************/
using std::cin;
using std::cout;
using std::endl;
using std::string;

/******************* Type Definitions *********************/
/* For enums: Try to namesapce the common elements.
 * typedef enum {
 *	VAL_,
 * } name_e;
 */

/* For structs:
 * typedef struct name_s {
 *	int index;
 * } name_t;
 */

/****************** Class Definitions *********************/

/****************** Global Functions **********************/
int fib(int n) {
	if (n < 0)
		return 0;
	if (n < 2)
		return n;

	int f_n2 = 0, f_n1 = 1, f_n = 0, t = 1;
	while(t++ != n) {
		f_n = f_n2 + f_n1;
		f_n2 = f_n1;
		f_n1 = f_n;
	}

	return f_n;
}

int factorial(int n) {
	if (n <= 1)
		return 1;

	int fact = 1;
	do {
		fact *= n;
	} while (n-- != 1);

	return fact;
}

void testAssert() {
	std::vector<int> v, v2;
	v.push_back(1);
	v2.push_back(1);

	ASSERT_EQ(v.size(), v2.size());

	for (std::vector<int>::size_type i = 0; i < v.size(); ++i) {
		EXPECT_EQ(v[i], v2[i]) << "Vectors v & v2 differ at index " << i;
	}
}

TEST(FibTest, HandlesZeroInput) {
	EXPECT_EQ(0, fib(0));
}

TEST(FibTest, HandlesPositiveInput) {
	EXPECT_EQ(1, fib(1));
	EXPECT_EQ(1, fib(2));
	EXPECT_EQ(2, fib(3));
	EXPECT_EQ(21, fib(8));
}

TEST(FactTest, HandlesPositiveInput) {
	EXPECT_EQ(1, factorial(1));
	EXPECT_EQ(6, factorial(3));
	EXPECT_EQ(720, factorial(6));
	EXPECT_EQ(5040, factorial(7));
}

/**
 * Main loop of the function.
 */
int main(int argc, char **argv) {
	::testing::InitGoogleTest(&argc, argv);
	testAssert();
	return RUN_ALL_TESTS();
}

/* Notes:
 * Force call to use another version of virtual function: baseP->Item_base::net_price(42);
 *
 */
<commit_msg>Example with fixtures.<commit_after>/**
 * Template C++ file.
 * Function with references to pointers: func(int *&ptr);
 */
/********************* Header Files ***********************/
/* C++ Headers */
#include <iostream> /* Input/output objects. */
//#include <fstream> /* File operations. */
//#include <sstream> /* String stream. */
#include <string> /* C++ String class. */
//#include <new> /* Defines bad_malloc exception, new functions. */
//#include <typeinfo> /* Casting header. */
//#include <exception> /* Top level exception header. */
//#include <stdexcept> /* Derived exception classes. */

/* STL Headers */
#include <vector>
//#include <list>
//#include <deque>
//#include <stack>
//#include <queue>
//#include <priority_queue>
//#include <bitset>
//#include <set> // multiset for multiple keys allowed.
//#include <map> // multimap for multiple keys allowed.
//#include <utility> // Has pair for map.
//#include <algorithm>
//#include <numeric>
//#include <functional> // Functional objects.
//#include <iterator> // Contains back_inserter function and like.

/* C Headers */
//#include <cstdlib>
//#include <cstddef>
//#include <cctype>
//#include <cstring>
//#include <cstdio>
//#include <climits>
//#include <cassert>

/* Project Headers */
#include "gtest/gtest.h"

/******************* Constants/Macros *********************/

/**************** Namespace Declarations ******************/
using std::cin;
using std::cout;
using std::endl;
using std::string;

/******************* Type Definitions *********************/
/* For enums: Try to namesapce the common elements.
 * typedef enum {
 *	VAL_,
 * } name_e;
 */

/* For structs:
 * typedef struct name_s {
 *	int index;
 * } name_t;
 */

/****************** Class Definitions *********************/
template <typename E>
class Queue {
public:
	Queue() {};
	void Enqueue(const E& element) {
		q.insert(q.begin(), element);
	};
	E* Dequeue() { // return null if empty
		if (q.empty()) {
			return NULL;
		} else {
			E* val = &q.back();
			q.pop_back();
			return val;
		}

	};
	size_t size() const {
		return q.size();
	};
private:
	std::vector<E> q;
};

class QueueTest : public ::testing::Test {
protected:
	virtual void SetUp() {
		int val[] = {1, 2, 3};
		q1.Enqueue(val[0]);
		q2.Enqueue(val[1]);
		q2.Enqueue(val[2]);
	}

	virtual void TearDown() {
	}

	Queue<int> q0;
	Queue<int> q1;
	Queue<int> q2;
};

/****************** Global Functions **********************/
int fib(int n) {
	if (n < 0)
		return 0;
	if (n < 2)
		return n;

	int f_n2 = 0, f_n1 = 1, f_n = 0, t = 1;
	while(t++ != n) {
		f_n = f_n2 + f_n1;
		f_n2 = f_n1;
		f_n1 = f_n;
	}

	return f_n;
}

int factorial(int n) {
	if (n <= 1)
		return 1;

	int fact = 1;
	do {
		fact *= n;
	} while (n-- != 1);

	return fact;
}

void testAssert() {
	std::vector<int> v, v2;
	v.push_back(1);
	v2.push_back(1);

	ASSERT_EQ(v.size(), v2.size());

	for (std::vector<int>::size_type i = 0; i < v.size(); ++i) {
		EXPECT_EQ(v[i], v2[i]) << "Vectors v & v2 differ at index " << i;
	}
}

TEST(FibTest, HandlesZeroInput) {
	EXPECT_EQ(0, fib(0));
}

TEST(FibTest, HandlesPositiveInput) {
	EXPECT_EQ(1, fib(1));
	EXPECT_EQ(1, fib(2));
	EXPECT_EQ(2, fib(3));
	EXPECT_EQ(21, fib(8));
}

TEST(FactTest, HandlesPositiveInput) {
	EXPECT_EQ(1, factorial(1));
	EXPECT_EQ(6, factorial(3));
	EXPECT_EQ(720, factorial(6));
	EXPECT_EQ(5040, factorial(7));
}

TEST_F(QueueTest, IsEmptyInitially) {
	EXPECT_EQ(0, q0.size());
}

TEST_F(QueueTest, DequeueWorks) {
	int *n = q0.Dequeue();
	EXPECT_EQ(NULL, n);

	n = q1.Dequeue();
	ASSERT_TRUE(n != NULL);
	EXPECT_EQ(1, *n);
	EXPECT_EQ(0, q1.size());

	n = q2.Dequeue();
	ASSERT_TRUE(n != NULL);
	EXPECT_EQ(2, *n);
	EXPECT_EQ(1, q2.size());
}

/**
 * Main loop of the function.
 */
int main(int argc, char **argv) {
	::testing::InitGoogleTest(&argc, argv);
	testAssert();
	return RUN_ALL_TESTS();
}

/* Notes:
 * Force call to use another version of virtual function: baseP->Item_base::net_price(42);
 *
 */
<|endoftext|>