<commit_before>/****************************************************************************
*
*   Copyright (c) 2015 PX4 Development Team. All rights reserved.
*      Author: Pavel Kirienko <pavel.kirienko@gmail.com>
*              David Sidrane <david_s5@usa.net>
*
****************************************************************************/

#ifndef UAVCAN_POSIX_BASIC_FILE_SERVER_BACKEND_HPP_INCLUDED
#define UAVCAN_POSIX_BASIC_FILE_SERVER_BACKEND_HPP_INCLUDED

#include <sys/stat.h>
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>

#include <uavcan/data_type.hpp>
#include <uavcan/protocol/file/Error.hpp>
#include <uavcan/protocol/file/EntryType.hpp>
#include <uavcan/protocol/file/Read.hpp>
#include <uavcan/protocol/file_server.hpp>
#include <uavcan/data_type.hpp>

namespace uavcan_posix
{
/**
 * This interface implements a POSIX compliant IFileServerBackend interface
 */
class BasicFileSeverBackend : public uavcan::IFileServerBackend
{
    enum { FilePermissions = 438 };   ///< 0o666

protected:
    class FDCacheBase
    {
    public:
        FDCacheBase() { }
        virtual ~FDCacheBase() { }

        virtual int open(const char* path, int oflags)
        {
            using namespace std;

            return ::open(path, oflags);
        }

        virtual int close(int fd, bool done = true)
        {
            using namespace std;

            return ::close(fd);
        }
    };

    FDCacheBase fallback_;

    class FDCache : public FDCacheBase
    {
        enum { MaxAgeSeconds = 3 };

        class FDCacheItem
        {
            friend FDCache;
            FDCacheItem* next_;
            time_t last_access_;
            int fd_;
            int oflags_;
            const char* path_;

        public:
            enum { InvalidFD = -1 };

            FDCacheItem()
                : next_(NULL)
                , last_access_(0)
                , fd_(InvalidFD)
                , oflags_(0)
                , path_(0)
            { }

            FDCacheItem(int fd, const char* path, int oflags)
                : next_(NULL)
                , last_access_(0)
                , fd_(fd)
                , oflags_(oflags)
                , path_(strdup(path))
            { }

            ~FDCacheItem()
            {
                if (valid())
                {
                    delete path_;
                }
            }

            inline bool valid()
            {
                return path_ != NULL;
            }

            inline int getFD()
            {
                return fd_;
            }

            inline time_t getAccess()
            {
                return last_access_;
            }

            time_t acessed()
            {
                last_access_ = time(NULL);
                return getAccess();
            }

            void expire()
            {
                last_access_ = 0;
            }

            bool expired()
            {
                return 0 == last_access_ || (time(NULL) - last_access_) > MaxAgeSeconds;
            }

            int compare(const char* path, int oflags)
            {
                return (oflags_ == oflags && 0 == ::strcmp(path, path_)) ? 0 : 1;
            }

            int compare(int fd)
            {
                return fd_ == fd ? 0 : 1;
            }
        };

        FDCacheItem* head_;

        FDCacheItem* find(const char* path, int oflags)
        {
            for(FDCacheItem* pi = head_; pi; pi = pi->next_)
            {
                if (0 == pi->compare(path, oflags))
                {
                    return pi;
                }
            }
            return NULL;
        }

        FDCacheItem* find(int fd)
        {
            for(FDCacheItem* pi = head_; pi; pi = pi->next_)
            {
                if(0 == pi->compare(fd))
                {
                    return pi;
                }
            }
            return 0;
        }

        FDCacheItem* add(FDCacheItem* pi)
        {
            pi->next_ = head_;
            head_ = pi;
            pi->acessed();
            return pi;
        }

        void removeExpired(FDCacheItem** pi)
        {
            while (*pi)
            {
                if ((*pi)->expired())
                {
                    FDCacheItem* next = (*pi)->next_;
                    (void)FDCacheBase::close((*pi)->fd_);
                    delete(*pi);
                    *pi = next;
                    continue;
                }
                pi = &(*pi)->next_;
            }
        }

        void remove(FDCacheItem* pi, bool done)
        {
            if (done)
            {
                pi->expire();
            }
            removeExpired(&head_);
        }

        void clear()
        {
            FDCacheItem* tmp;
            for(FDCacheItem* pi = head_; pi; pi = tmp)
            {
                tmp = pi->next_;
                (void)FDCacheBase::close(pi->fd_);
                delete pi;
            }
        }

    public:
        FDCache()
            : head_(NULL)
        { }

        virtual ~FDCache()
        {
            clear();
        }

        virtual int open(const char* path, int oflags)
        {
            int fd = FDCacheItem::InvalidFD;

            FDCacheItem* pi = find(path, oflags);

            if (pi != NULL)
            {
                pi->acessed();
            }
            else
            {
                fd = FDCacheBase::open(path, oflags);
                if (fd < 0)
                {
                    return fd;
                }

                /* Allocate and clone path */

                pi = new FDCacheItem(fd, path, oflags);

                /* Allocation worked but check clone */

                if (pi && !pi->valid())
                {
                    /* Allocation worked but clone or path failed */

                    delete pi;
                    pi = NULL;
                }

                if (pi == NULL)
                {
                    /*
                     * If allocation fails no harm just can not cache it
                     * return open fd
                     */

                    return fd;
                }
                /* add new */
                add(pi);
            }
            return pi->getFD();
        }

        virtual int close(int fd, bool done)
        {
            FDCacheItem* pi = find(fd);
            if (pi == NULL)
            {
                /*
                 * If not found just close it
                 */
                return FDCacheBase::close(fd);
            }
            remove(pi, done);
            return 0;
        }
    };

    FDCacheBase* fdcache_;

    FDCacheBase&  getFDCache()
    {
        if (fdcache_ == NULL)
        {
            fdcache_ = new FDCache();

            if (fdcache_ == NULL)
            {
                fdcache_ = &fallback_;
            }
        }
        return *fdcache_;
    }

    /**
     * Back-end for uavcan.protocol.file.GetInfo.
     * Implementation of this method is required.
     * On success the method must return zero.
     */
    virtual int16_t getInfo(const Path& path, uint64_t& out_size, EntryType& out_type)
    {
        int rv = uavcan::protocol::file::Error::INVALID_VALUE;

        if (path.size() > 0)
        {
            using namespace std;

            struct stat sb;

            rv = stat(path.c_str(), &sb);

            if (rv < 0)
            {
                rv = errno;
            }
            else
            {
                rv = 0;
                out_size = sb.st_size;
                out_type.flags = uavcan::protocol::file::EntryType::FLAG_READABLE;
                if (S_ISDIR(sb.st_mode))
                {
                    out_type.flags |= uavcan::protocol::file::EntryType::FLAG_DIRECTORY;
                }
                else if (S_ISREG(sb.st_mode))
                {
                    out_type.flags |= uavcan::protocol::file::EntryType::FLAG_FILE;
                }
                // TODO Using fixed flag FLAG_READABLE until we add file permission checks to return actual value.
            }
        }
        return rv;
    }

    /**
     * Back-end for uavcan.protocol.file.Read.
     * Implementation of this method is required.
     * @ref inout_size is set to @ref ReadSize; read operation is required to return exactly this amount, except
     * if the end of file is reached.
     * On success the method must return zero.
     */
    virtual int16_t read(const Path& path, const uint64_t offset, uint8_t* out_buffer, uint16_t& inout_size)
    {
        int rv = uavcan::protocol::file::Error::INVALID_VALUE;

        if (path.size() > 0)
        {
            FDCacheBase& cache = getFDCache();
            int fd = cache.open(path.c_str(), O_RDONLY);

            if (fd < 0)
            {
                rv = errno;
            }
            else
            {
                rv = ::lseek(fd, offset, SEEK_SET);

                ssize_t len = 0;

                if (rv < 0)
                {
                    rv = errno;
                }
                else
                {
                    // TODO use a read at offset to fill on EAGAIN
                    len = ::read(fd, out_buffer, inout_size);

                    if (len < 0)
                    {
                        rv = errno;
                    }
                    else
                    {
                        rv = 0;
                    }
                }

                (void)cache.close(fd, rv != 0 || len != inout_size);
                inout_size = len;
            }
        }
        return rv;
    }

public:
    BasicFileSeverBackend()
        : fdcache_(NULL)
    { }

    ~BasicFileSeverBackend()
    {
        if (fdcache_ != &fallback_)
        {
            delete fdcache_;
            fdcache_ = NULL;
        }
    }
};
}

#endif // Include guard
<commit_msg>Fixed naming and CV-correctness<commit_after>/****************************************************************************
*
*   Copyright (c) 2015 PX4 Development Team. All rights reserved.
*      Author: Pavel Kirienko <pavel.kirienko@gmail.com>
*              David Sidrane <david_s5@usa.net>
*
****************************************************************************/

#ifndef UAVCAN_POSIX_BASIC_FILE_SERVER_BACKEND_HPP_INCLUDED
#define UAVCAN_POSIX_BASIC_FILE_SERVER_BACKEND_HPP_INCLUDED

#include <sys/stat.h>
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>

#include <uavcan/data_type.hpp>
#include <uavcan/protocol/file/Error.hpp>
#include <uavcan/protocol/file/EntryType.hpp>
#include <uavcan/protocol/file/Read.hpp>
#include <uavcan/protocol/file_server.hpp>
#include <uavcan/data_type.hpp>

namespace uavcan_posix
{
/**
 * This interface implements a POSIX compliant IFileServerBackend interface
 */
class BasicFileSeverBackend : public uavcan::IFileServerBackend
{
    enum { FilePermissions = 438 };   ///< 0o666

protected:
    class FDCacheBase
    {
    public:
        FDCacheBase() { }
        virtual ~FDCacheBase() { }

        virtual int open(const char* path, int oflags)
        {
            using namespace std;

            return ::open(path, oflags);
        }

        virtual int close(int fd, bool done = true)
        {
            using namespace std;

            return ::close(fd);
        }
    };

    FDCacheBase fallback_;

    class FDCache : public FDCacheBase
    {
        enum { MaxAgeSeconds = 3 };

        class FDCacheItem
        {
            friend FDCache;

            FDCacheItem* next_;
            time_t last_access_;
            int fd_;
            int oflags_;
            const char* path_;

        public:
            enum { InvalidFD = -1 };

            FDCacheItem()
                : next_(NULL)
                , last_access_(0)
                , fd_(InvalidFD)
                , oflags_(0)
                , path_(0)
            { }

            FDCacheItem(int fd, const char* path, int oflags)
                : next_(NULL)
                , last_access_(0)
                , fd_(fd)
                , oflags_(oflags)
                , path_(strdup(path))
            { }

            ~FDCacheItem()
            {
                if (valid())
                {
                    delete path_;
                }
            }

            bool valid() const
            {
                return path_ != NULL;
            }

            int getFD() const
            {
                return fd_;
            }

            time_t getAccess() const
            {
                return last_access_;
            }

            time_t acessed()
            {
                last_access_ = time(NULL);
                return getAccess();
            }

            void expire()
            {
                last_access_ = 0;
            }

            bool expired() const
            {
                return 0 == last_access_ || (time(NULL) - last_access_) > MaxAgeSeconds;
            }

            bool equals(const char* path, int oflags) const
            {
                return oflags_ == oflags &&
                       0 == ::strcmp(path, path_);
            }

            bool equals(int fd) const
            {
                return fd_ == fd;
            }
        };

        FDCacheItem* head_;

        FDCacheItem* find(const char* path, int oflags)
        {
            for(FDCacheItem* pi = head_; pi; pi = pi->next_)
            {
                if (pi->equals(path, oflags))
                {
                    return pi;
                }
            }
            return NULL;
        }

        FDCacheItem* find(int fd)
        {
            for(FDCacheItem* pi = head_; pi; pi = pi->next_)
            {
                if(pi->equals(fd))
                {
                    return pi;
                }
            }
            return 0;
        }

        FDCacheItem* add(FDCacheItem* pi)
        {
            pi->next_ = head_;
            head_ = pi;
            pi->acessed();
            return pi;
        }

        void removeExpired(FDCacheItem** pi)
        {
            while (*pi)
            {
                if ((*pi)->expired())
                {
                    FDCacheItem* next = (*pi)->next_;
                    (void)FDCacheBase::close((*pi)->fd_);
                    delete(*pi);
                    *pi = next;
                    continue;
                }
                pi = &(*pi)->next_;
            }
        }

        void remove(FDCacheItem* pi, bool done)
        {
            if (done)
            {
                pi->expire();
            }
            removeExpired(&head_);
        }

        void clear()
        {
            FDCacheItem* tmp;
            for(FDCacheItem* pi = head_; pi; pi = tmp)
            {
                tmp = pi->next_;
                (void)FDCacheBase::close(pi->fd_);
                delete pi;
            }
        }

    public:
        FDCache()
            : head_(NULL)
        { }

        virtual ~FDCache()
        {
            clear();
        }

        virtual int open(const char* path, int oflags)
        {
            int fd = FDCacheItem::InvalidFD;

            FDCacheItem* pi = find(path, oflags);

            if (pi != NULL)
            {
                pi->acessed();
            }
            else
            {
                fd = FDCacheBase::open(path, oflags);
                if (fd < 0)
                {
                    return fd;
                }

                /* Allocate and clone path */

                pi = new FDCacheItem(fd, path, oflags);

                /* Allocation worked but check clone */

                if (pi && !pi->valid())
                {
                    /* Allocation worked but clone or path failed */

                    delete pi;
                    pi = NULL;
                }

                if (pi == NULL)
                {
                    /*
                     * If allocation fails no harm just can not cache it
                     * return open fd
                     */

                    return fd;
                }
                /* add new */
                add(pi);
            }
            return pi->getFD();
        }

        virtual int close(int fd, bool done)
        {
            FDCacheItem* pi = find(fd);
            if (pi == NULL)
            {
                /*
                 * If not found just close it
                 */
                return FDCacheBase::close(fd);
            }
            remove(pi, done);
            return 0;
        }
    };

    FDCacheBase* fdcache_;

    FDCacheBase&  getFDCache()
    {
        if (fdcache_ == NULL)
        {
            fdcache_ = new FDCache();

            if (fdcache_ == NULL)
            {
                fdcache_ = &fallback_;
            }
        }
        return *fdcache_;
    }

    /**
     * Back-end for uavcan.protocol.file.GetInfo.
     * Implementation of this method is required.
     * On success the method must return zero.
     */
    virtual int16_t getInfo(const Path& path, uint64_t& out_size, EntryType& out_type)
    {
        int rv = uavcan::protocol::file::Error::INVALID_VALUE;

        if (path.size() > 0)
        {
            using namespace std;

            struct stat sb;

            rv = stat(path.c_str(), &sb);

            if (rv < 0)
            {
                rv = errno;
            }
            else
            {
                rv = 0;
                out_size = sb.st_size;
                out_type.flags = uavcan::protocol::file::EntryType::FLAG_READABLE;
                if (S_ISDIR(sb.st_mode))
                {
                    out_type.flags |= uavcan::protocol::file::EntryType::FLAG_DIRECTORY;
                }
                else if (S_ISREG(sb.st_mode))
                {
                    out_type.flags |= uavcan::protocol::file::EntryType::FLAG_FILE;
                }
                // TODO Using fixed flag FLAG_READABLE until we add file permission checks to return actual value.
            }
        }
        return rv;
    }

    /**
     * Back-end for uavcan.protocol.file.Read.
     * Implementation of this method is required.
     * @ref inout_size is set to @ref ReadSize; read operation is required to return exactly this amount, except
     * if the end of file is reached.
     * On success the method must return zero.
     */
    virtual int16_t read(const Path& path, const uint64_t offset, uint8_t* out_buffer, uint16_t& inout_size)
    {
        int rv = uavcan::protocol::file::Error::INVALID_VALUE;

        if (path.size() > 0)
        {
            FDCacheBase& cache = getFDCache();
            int fd = cache.open(path.c_str(), O_RDONLY);

            if (fd < 0)
            {
                rv = errno;
            }
            else
            {
                rv = ::lseek(fd, offset, SEEK_SET);

                ssize_t len = 0;

                if (rv < 0)
                {
                    rv = errno;
                }
                else
                {
                    // TODO use a read at offset to fill on EAGAIN
                    len = ::read(fd, out_buffer, inout_size);

                    if (len < 0)
                    {
                        rv = errno;
                    }
                    else
                    {
                        rv = 0;
                    }
                }

                (void)cache.close(fd, rv != 0 || len != inout_size);
                inout_size = len;
            }
        }
        return rv;
    }

public:
    BasicFileSeverBackend()
        : fdcache_(NULL)
    { }

    ~BasicFileSeverBackend()
    {
        if (fdcache_ != &fallback_)
        {
            delete fdcache_;
            fdcache_ = NULL;
        }
    }
};
}

#endif // Include guard
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// QmitkFctMediator.cpp: implementation of the QmitkFctMediator class.
//
//////////////////////////////////////////////////////////////////////

#include "QmitkFctMediator.h"

#include <qwidgetstack.h>
#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qtoolbar.h>
#include <qaction.h>
#include <qlayout.h>

#include <stdio.h>

#include <qapplication.h>
#include <QmitkControlsRightFctLayoutTemplate.h>

const QSizePolicy ignored(QSizePolicy::Ignored, QSizePolicy::Ignored);
const QSizePolicy preferred(QSizePolicy::Preferred, QSizePolicy::Preferred);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

QmitkFctMediator::QmitkFctMediator(QObject *parent, const char *name) : QObject(parent, name),
                                                                        m_LayoutTemplate(NULL),
                                                                       m_MainStack(NULL),
                                                                       m_ControlStack(NULL),
                                                                       m_ButtonMenu(NULL),
                                                                       m_ToolBar(NULL),
                                                                       m_DefaultMain(NULL),
                                                                       m_NumOfFuncs(0),
                                                                       m_FunctionalityActionGroup(NULL),
                                                                       m_CurrentFunctionality(0)
{

}

QmitkFctMediator::~QmitkFctMediator()
{
  QmitkFunctionality *functionality;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next() )
    delete functionality;
  qfl.clear();
}

void QmitkFctMediator::Initialize(QWidget *aLayoutTemplate)
{
  if(aLayoutTemplate==NULL)
    return;

  if(m_NumOfFuncs>0)
    itkGenericOutputMacro(<<"Number of functionalities >0 ("<<m_NumOfFuncs<<") at initialize().");

  // why is this cast done ? I remember we wanted an option for playing controls right...
  m_LayoutTemplate = static_cast<QWidget*>(aLayoutTemplate->child("LayoutTemplate", "QmitkControlsRightFctLayoutTemplate"));

  if ( m_LayoutTemplate == NULL) {
    m_LayoutTemplate = static_cast<QWidget*>(aLayoutTemplate->child("LayoutTemplate", "QmitkControlsLeftFctLayoutTemplate"));
  }

  assert (m_LayoutTemplate);

  QWidget *w;

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("MainParent", "QWidget")))!=NULL)
  {
    QHBoxLayout* hlayout=new QHBoxLayout(w);
    hlayout->setAutoAdd(true);
    m_MainStack = new QWidgetStack(w, "QmitkFctMediator::mainStack");

    //m_MainStack->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum, 1, 0, m_MainStack->sizePolicy().hasHeightForWidth()) );

    m_DefaultMain = new QWidget(m_MainStack,"QmitkFctMediator::m_DefaultMain");
    m_MainStack->addWidget(m_DefaultMain, 0);

    connect( m_MainStack, SIGNAL(aboutToShow(int)), this, SLOT(FunctionalitySelected(int)) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ControlParent", "QWidget")))!=NULL)
  {
    QHBoxLayout* hlayout=new QHBoxLayout(w);
    hlayout->setAutoAdd(true);
    m_ControlStack = new QWidgetStack(w, "QmitkFctMediator::controlStack");
    //m_ControlStack->setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, 0, 1, m_ControlStack->sizePolicy().hasHeightForWidth()) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ButtonMenuParent", "QButtonGroup")))!=NULL)
  {
    m_ButtonMenu=static_cast<QButtonGroup*>(w);
    m_ButtonMenu->setExclusive(true);
    if(m_ButtonMenu!=NULL)
      connect( m_ButtonMenu, SIGNAL(clicked(int)), this, SLOT(RaiseFunctionality(int)) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ToolBar", "QWidget")))!=NULL)
  {
    m_ToolBar=w;

    m_FunctionalityActionGroup = new QActionGroup( this );
    m_FunctionalityActionGroup->setExclusive( TRUE );

    connect( m_FunctionalityActionGroup, SIGNAL( selected( QAction* ) ), this, SLOT( RaiseFunctionality( QAction* ) ) );
  }
}

bool QmitkFctMediator::AddFunctionality(QmitkFunctionality * functionality)
{
  if(functionality==NULL)
  {
    if(m_ButtonMenu!=NULL)
    {
      QLayout * menuLayout = m_ButtonMenu->layout();
      QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
      menuLayout->addItem( spacer );
    }
    return true;
  }

  qfl.append(functionality);

  connect(functionality, SIGNAL(AvailabilityChanged()), this, SLOT(CheckAvailability()));

  QPushButton* funcButton=NULL;
  if(m_ButtonMenu!=NULL)
  {
    QLayout * menuLayout = m_ButtonMenu->layout();
    if(menuLayout==NULL)
    {
      menuLayout = new QVBoxLayout(m_ButtonMenu,0,10);
      menuLayout->setSpacing( 2 );
      menuLayout->setMargin( 11 );
    }

    char number[20]; sprintf(number,"%d",m_NumOfFuncs);

    funcButton = new QPushButton(functionality->GetFunctionalityName(), m_ButtonMenu, number);
    funcButton->setToggleButton(true);
    menuLayout->addItem(new QWidgetItem(funcButton));

    if((qfl.count()>1) && (functionality->IsAvailable()==false))
      funcButton->setEnabled(false);
  }

  QAction* action=NULL;
  if(m_FunctionalityActionGroup!=NULL)
  {

    action = functionality->CreateAction(m_FunctionalityActionGroup);
    if(action!=NULL)
    {
      action->setToggleAction( true );
      if(m_ToolBar!=NULL)
        action->addTo( m_ToolBar );
    }
  }
  qal.append(action);

  if(m_MainStack!=NULL)
  {
    QWidget * mainWidget = functionality->CreateMainWidget(m_MainStack);
    if((mainWidget!=NULL) && (mainWidget->parent()!=m_DefaultMain))
    {
      mainWidget->setSizePolicy(ignored);
      m_MainStack->addWidget(mainWidget, m_NumOfFuncs+1);
    }
    else
      m_MainStack->addWidget(new QWidget(m_MainStack, "QmitkFctMediator::dummyMain"), m_NumOfFuncs+1);
  }
  if(m_ControlStack!=NULL)
  {
    QWidget * controlWidget = functionality->CreateControlWidget(m_ControlStack);
    if(controlWidget!=NULL)
    {
      controlWidget->setSizePolicy(ignored);
      m_ControlStack->addWidget(controlWidget, m_NumOfFuncs);
    }
    else
      m_ControlStack->addWidget(new QWidget(m_ControlStack, "QmitkFctMediator::dummyControl"), m_NumOfFuncs);
  }

  if(m_NumOfFuncs==0)
  {
    if(funcButton!=NULL)
      funcButton->setOn(true);
    if(action!=NULL)
      action->setOn(true);
    if(m_ControlStack!=NULL)
      m_ControlStack->raiseWidget(0);
    if((m_MainStack!=NULL) && (strcmp(m_MainStack->widget(0+1)->name(),"QmitkFctMediator::dummyMain")!=0))
      m_MainStack->raiseWidget(0+1);
  }

  functionality->CreateConnections();

  ++m_NumOfFuncs;

  return true;
}

QWidget * QmitkFctMediator::GetControlParent()
{
  return m_ControlStack;
}

QWidget * QmitkFctMediator::GetMainParent()
{
  return m_MainStack;
}

QButtonGroup * QmitkFctMediator::GetButtonMenu()
{
  return m_ButtonMenu;
}

QWidget * QmitkFctMediator::GetToolBar()
{
  return m_ToolBar;
}

QWidget * QmitkFctMediator::GetDefaultMain()
{
  return m_DefaultMain;
}

void QmitkFctMediator::Selecting(int id)
{
  if(id!=m_CurrentFunctionality)
  {
    qfl.at(m_CurrentFunctionality)->Deactivated();
    if(qfl.at(m_CurrentFunctionality)->m_Activated)
    {
      itkGenericOutputMacro(<<"Method Deactivated() of functionality '"<<qfl.at(m_CurrentFunctionality)->GetFunctionalityName().latin1()<< "' did not call QmitkFunctionality::Deactivated().");
      qfl.at(m_CurrentFunctionality)->m_Activated = false;
    }
  }
}

void QmitkFctMediator::FunctionalitySelected(int id)
{
  if(id==0) return;
  m_CurrentFunctionality=id-1; //kommt von m_MainStack und der hat einen Eintrag mehr (wg. m_DefaultMain)
  qfl.at(m_CurrentFunctionality)->Activated();
  if(qfl.at(m_CurrentFunctionality)->m_Activated==false)
  {
    itkGenericOutputMacro(<<"Method Activated() of functionality '"<<qfl.at(m_CurrentFunctionality)->GetFunctionalityName().latin1()<< "' did not call QmitkFunctionality::Activated(). TreeChanged() will not work!!");
    qfl.at(m_CurrentFunctionality)->m_Activated = true;
  }
}

QmitkFunctionality* QmitkFctMediator::GetFunctionalityByName(const char *name)
{
  QmitkFunctionality *functionality;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next() )
    if(strcmp(functionality->GetFunctionalityName().ascii(),name)==0)
      return functionality;
  return NULL;
}

int QmitkFctMediator::GetFunctionalityIdByName( const char * name ) {

  QmitkFunctionality *functionality;
  int id = 0;

  for ( functionality = qfl.first(); functionality != NULL; functionality = qfl.next(), id++ )
  {
    if(strcmp(functionality->GetFunctionalityName().ascii(),name)==0)
      return id;
  }

  return -1;
}

void QmitkFctMediator::RaiseFunctionality(int id)
{
  QAction *action;
  action=qal.at(id);
  if((action!=NULL) && (action->isOn()==false))
  {
    action->setOn(true);
    return; //we will come into this method again ...
  }

  if(m_ButtonMenu!=NULL)
    ((QButtonGroup*)m_ButtonMenu)->setButton(id);
  if(m_ToolBar!=NULL)
    ((QButtonGroup*)m_ToolBar)->setButton(id);

  Selecting(id);
  QWidget *oldVisibleWidget, *newVisibleWidget;
  QSize osize, nsize;

  oldVisibleWidget = m_ControlStack->visibleWidget();
  newVisibleWidget = m_ControlStack->widget(id);
  if((oldVisibleWidget!=NULL) && (oldVisibleWidget!=newVisibleWidget))
  {
    osize=oldVisibleWidget->minimumSizeHint();
    oldVisibleWidget->setSizePolicy(ignored);
    newVisibleWidget->setSizePolicy(ignored);
  }
  m_ControlStack->raiseWidget(newVisibleWidget);

  m_LayoutTemplate->layout()->activate();
  nsize=newVisibleWidget->minimumSizeHint();

  oldVisibleWidget = m_MainStack->visibleWidget();
  newVisibleWidget = m_MainStack->widget(id+1);
  if(strcmp(newVisibleWidget->name(),"QmitkFctMediator::dummyMain")==0)
    newVisibleWidget = m_MainStack->widget(0);
  if((oldVisibleWidget!=NULL) && (oldVisibleWidget!=newVisibleWidget))
  {
    oldVisibleWidget->setSizePolicy(ignored);
    newVisibleWidget->setSizePolicy(preferred);
  }
  m_MainStack->raiseWidget(newVisibleWidget);

  if(m_LayoutTemplate!=NULL)
    ((QmitkControlsRightFctLayoutTemplate*)m_LayoutTemplate)->setControlSizeHint(&nsize);
  //    QApplication::sendPostedEvents(0, QEvent::LayoutHint);

  FunctionalitySelected(id+1);
}

void QmitkFctMediator::RaiseFunctionality(QAction* action)
{
  int id=qal.find(action);
  if(id>=0)
    RaiseFunctionality(id);
}

void QmitkFctMediator::RaiseFunctionality(QmitkFunctionality* aFunctionality)
{
  QmitkFunctionality *functionality;
  int id=0;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next(),++id )
    if(functionality==aFunctionality)
    {
      RaiseFunctionality(id);
      return;
    }
}

void QmitkFctMediator::CheckAvailability()
{
  QmitkFunctionality *functionality;
  int id;
  if(m_ButtonMenu!=NULL)
    for ( functionality=qfl.first(), id=0; functionality != 0; functionality=qfl.next(),++id )
      ((QButtonGroup*)m_ButtonMenu)->find(id)->setEnabled(functionality->IsAvailable());
}

void QmitkFctMediator::HideControls(bool hide)
{
  if(m_ControlStack==NULL) return;

  QWidget *controlStackParent = dynamic_cast<QWidget*>(m_ControlStack->parent());
  if(controlStackParent==NULL) return;

  if(hide)
    controlStackParent->hide();
  else
    controlStackParent->show();
}

void QmitkFctMediator::HideMenu(bool hide)
{
  if(m_ButtonMenu==NULL) return;

  if(hide)
    m_ButtonMenu->hide();
  else
    m_ButtonMenu->show();
}

int QmitkFctMediator::GetActiveFunctionalityId() const
{
  return m_CurrentFunctionality;
}

QmitkFunctionality* QmitkFctMediator::GetActiveFunctionality()
{
  return qfl.at(m_CurrentFunctionality);
}

QmitkFunctionality* QmitkFctMediator::GetFunctionalityById(int id)
{
  return qfl.at(id);
}

unsigned int QmitkFctMediator::GetFunctionalityCount()
{
  return m_NumOfFuncs;
}
<commit_msg>FIX bug #119: MITKSampleApp - flickers when switching functionalities flicker removed. resizing problems remain in some functionalities...<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// QmitkFctMediator.cpp: implementation of the QmitkFctMediator class.
//
//////////////////////////////////////////////////////////////////////

#include "QmitkFctMediator.h"

#include <qwidgetstack.h>
#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qtoolbar.h>
#include <qaction.h>
#include <qlayout.h>

#include <stdio.h>

#include <qapplication.h>
#include <QmitkControlsRightFctLayoutTemplate.h>

const QSizePolicy ignored(QSizePolicy::Ignored, QSizePolicy::Ignored);
const QSizePolicy preferred(QSizePolicy::Preferred, QSizePolicy::Preferred);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

QmitkFctMediator::QmitkFctMediator(QObject *parent, const char *name) : QObject(parent, name),
                                                                        m_LayoutTemplate(NULL),
                                                                       m_MainStack(NULL),
                                                                       m_ControlStack(NULL),
                                                                       m_ButtonMenu(NULL),
                                                                       m_ToolBar(NULL),
                                                                       m_DefaultMain(NULL),
                                                                       m_NumOfFuncs(0),
                                                                       m_FunctionalityActionGroup(NULL),
                                                                       m_CurrentFunctionality(0)
{

}

QmitkFctMediator::~QmitkFctMediator()
{
  QmitkFunctionality *functionality;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next() )
    delete functionality;
  qfl.clear();
}

void QmitkFctMediator::Initialize(QWidget *aLayoutTemplate)
{
  if(aLayoutTemplate==NULL)
    return;

  if(m_NumOfFuncs>0)
    itkGenericOutputMacro(<<"Number of functionalities >0 ("<<m_NumOfFuncs<<") at initialize().");

  // why is this cast done ? I remember we wanted an option for playing controls right...
  m_LayoutTemplate = static_cast<QWidget*>(aLayoutTemplate->child("LayoutTemplate", "QmitkControlsRightFctLayoutTemplate"));

  if ( m_LayoutTemplate == NULL) {
    m_LayoutTemplate = static_cast<QWidget*>(aLayoutTemplate->child("LayoutTemplate", "QmitkControlsLeftFctLayoutTemplate"));
  }

  assert (m_LayoutTemplate);

  QWidget *w;

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("MainParent", "QWidget")))!=NULL)
  {
    QHBoxLayout* hlayout=new QHBoxLayout(w);
    hlayout->setAutoAdd(true);
    m_MainStack = new QWidgetStack(w, "QmitkFctMediator::mainStack");

    //m_MainStack->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum, 1, 0, m_MainStack->sizePolicy().hasHeightForWidth()) );

    m_DefaultMain = new QWidget(m_MainStack,"QmitkFctMediator::m_DefaultMain");
    m_MainStack->addWidget(m_DefaultMain, 0);

    connect( m_MainStack, SIGNAL(aboutToShow(int)), this, SLOT(FunctionalitySelected(int)) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ControlParent", "QWidget")))!=NULL)
  {
    QHBoxLayout* hlayout=new QHBoxLayout(w);
    hlayout->setAutoAdd(true);
    m_ControlStack = new QWidgetStack(w, "QmitkFctMediator::controlStack");
    //m_ControlStack->setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, 0, 1, m_ControlStack->sizePolicy().hasHeightForWidth()) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ButtonMenuParent", "QButtonGroup")))!=NULL)
  {
    m_ButtonMenu=static_cast<QButtonGroup*>(w);
    m_ButtonMenu->setExclusive(true);
    if(m_ButtonMenu!=NULL)
      connect( m_ButtonMenu, SIGNAL(clicked(int)), this, SLOT(RaiseFunctionality(int)) );
  }

  if((w=static_cast<QWidget*>(aLayoutTemplate->child("ToolBar", "QWidget")))!=NULL)
  {
    m_ToolBar=w;

    m_FunctionalityActionGroup = new QActionGroup( this );
    m_FunctionalityActionGroup->setExclusive( TRUE );

    connect( m_FunctionalityActionGroup, SIGNAL( selected( QAction* ) ), this, SLOT( RaiseFunctionality( QAction* ) ) );
  }
}

bool QmitkFctMediator::AddFunctionality(QmitkFunctionality * functionality)
{
  if(functionality==NULL)
  {
    if(m_ButtonMenu!=NULL)
    {
      QLayout * menuLayout = m_ButtonMenu->layout();
      QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
      menuLayout->addItem( spacer );
    }
    return true;
  }

  qfl.append(functionality);

  connect(functionality, SIGNAL(AvailabilityChanged()), this, SLOT(CheckAvailability()));

  QPushButton* funcButton=NULL;
  if(m_ButtonMenu!=NULL)
  {
    QLayout * menuLayout = m_ButtonMenu->layout();
    if(menuLayout==NULL)
    {
      menuLayout = new QVBoxLayout(m_ButtonMenu,0,10);
      menuLayout->setSpacing( 2 );
      menuLayout->setMargin( 11 );
    }

    char number[20]; sprintf(number,"%d",m_NumOfFuncs);

    funcButton = new QPushButton(functionality->GetFunctionalityName(), m_ButtonMenu, number);
    funcButton->setToggleButton(true);
    menuLayout->addItem(new QWidgetItem(funcButton));

    if((qfl.count()>1) && (functionality->IsAvailable()==false))
      funcButton->setEnabled(false);
  }

  QAction* action=NULL;
  if(m_FunctionalityActionGroup!=NULL)
  {

    action = functionality->CreateAction(m_FunctionalityActionGroup);
    if(action!=NULL)
    {
      action->setToggleAction( true );
      if(m_ToolBar!=NULL)
        action->addTo( m_ToolBar );
    }
  }
  qal.append(action);

  if(m_MainStack!=NULL)
  {
    QWidget * mainWidget = functionality->CreateMainWidget(m_MainStack);
    if((mainWidget!=NULL) && (mainWidget->parent()!=m_DefaultMain))
    {
      mainWidget->setSizePolicy(ignored);
      m_MainStack->addWidget(mainWidget, m_NumOfFuncs+1);
    }
    else
      m_MainStack->addWidget(new QWidget(m_MainStack, "QmitkFctMediator::dummyMain"), m_NumOfFuncs+1);
  }
  if(m_ControlStack!=NULL)
  {
    QWidget * controlWidget = functionality->CreateControlWidget(m_ControlStack);
    if(controlWidget!=NULL)
    {
      controlWidget->setSizePolicy(preferred);
      m_ControlStack->addWidget(controlWidget, m_NumOfFuncs);
    }
    else
      m_ControlStack->addWidget(new QWidget(m_ControlStack, "QmitkFctMediator::dummyControl"), m_NumOfFuncs);
  }

  if(m_NumOfFuncs==0)
  {
    if(funcButton!=NULL)
      funcButton->setOn(true);
    if(action!=NULL)
      action->setOn(true);
    if(m_ControlStack!=NULL)
      m_ControlStack->raiseWidget(0);
    if((m_MainStack!=NULL) && (strcmp(m_MainStack->widget(0+1)->name(),"QmitkFctMediator::dummyMain")!=0))
      m_MainStack->raiseWidget(0+1);
  }

  functionality->CreateConnections();

  ++m_NumOfFuncs;

  return true;
}

QWidget * QmitkFctMediator::GetControlParent()
{
  return m_ControlStack;
}

QWidget * QmitkFctMediator::GetMainParent()
{
  return m_MainStack;
}

QButtonGroup * QmitkFctMediator::GetButtonMenu()
{
  return m_ButtonMenu;
}

QWidget * QmitkFctMediator::GetToolBar()
{
  return m_ToolBar;
}

QWidget * QmitkFctMediator::GetDefaultMain()
{
  return m_DefaultMain;
}

void QmitkFctMediator::Selecting(int id)
{
  if(id!=m_CurrentFunctionality)
  {
    qfl.at(m_CurrentFunctionality)->Deactivated();
    if(qfl.at(m_CurrentFunctionality)->m_Activated)
    {
      itkGenericOutputMacro(<<"Method Deactivated() of functionality '"<<qfl.at(m_CurrentFunctionality)->GetFunctionalityName().latin1()<< "' did not call QmitkFunctionality::Deactivated().");
      qfl.at(m_CurrentFunctionality)->m_Activated = false;
    }
  }
}

void QmitkFctMediator::FunctionalitySelected(int id)
{
  if(id==0) return;
  m_CurrentFunctionality=id-1; //kommt von m_MainStack und der hat einen Eintrag mehr (wg. m_DefaultMain)
  qfl.at(m_CurrentFunctionality)->Activated();
  if(qfl.at(m_CurrentFunctionality)->m_Activated==false)
  {
    itkGenericOutputMacro(<<"Method Activated() of functionality '"<<qfl.at(m_CurrentFunctionality)->GetFunctionalityName().latin1()<< "' did not call QmitkFunctionality::Activated(). TreeChanged() will not work!!");
    qfl.at(m_CurrentFunctionality)->m_Activated = true;
  }
}

QmitkFunctionality* QmitkFctMediator::GetFunctionalityByName(const char *name)
{
  QmitkFunctionality *functionality;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next() )
    if(strcmp(functionality->GetFunctionalityName().ascii(),name)==0)
      return functionality;
  return NULL;
}

int QmitkFctMediator::GetFunctionalityIdByName( const char * name )
{
  QmitkFunctionality *functionality;
  int id = 0;

  for ( functionality = qfl.first(); functionality != NULL; functionality = qfl.next(), id++ )
  {
    if(strcmp(functionality->GetFunctionalityName().ascii(),name)==0)
      return id;
  }

  return -1;
}

void QmitkFctMediator::RaiseFunctionality(int id)
{
  QAction *action;
  action=qal.at(id);
  if((action!=NULL) && (action->isOn()==false))
  {
    action->setOn(true);
    return; //we will come into this method again ...
  }

  if(m_ButtonMenu!=NULL)
    ((QButtonGroup*)m_ButtonMenu)->setButton(id);
  if(m_ToolBar!=NULL)
    ((QButtonGroup*)m_ToolBar)->setButton(id);

  Selecting(id);
  QWidget *oldVisibleWidget, *newVisibleWidget;

  newVisibleWidget = m_ControlStack->widget(id);
  m_ControlStack->raiseWidget(newVisibleWidget);

  if ( newVisibleWidget->minimumWidth() > 0 )
  {
    m_ControlStack->resize( newVisibleWidget->minimumSizeHint().width(), m_ControlStack->height() );
  }

  newVisibleWidget = m_MainStack->widget(id+1);
  if(strcmp(newVisibleWidget->name(),"QmitkFctMediator::dummyMain")==0)
    newVisibleWidget = m_MainStack->widget(0);

  m_MainStack->raiseWidget(newVisibleWidget);

  m_LayoutTemplate->layout()->activate();

  FunctionalitySelected(id+1);
}

void QmitkFctMediator::RaiseFunctionality(QAction* action)
{
  int id=qal.find(action);
  if(id>=0)
    RaiseFunctionality(id);
}

void QmitkFctMediator::RaiseFunctionality(QmitkFunctionality* aFunctionality)
{
  QmitkFunctionality *functionality;
  int id=0;
  for ( functionality=qfl.first(); functionality != 0; functionality=qfl.next(),++id )
    if(functionality==aFunctionality)
    {
      RaiseFunctionality(id);
      return;
    }
}

void QmitkFctMediator::CheckAvailability()
{
  QmitkFunctionality *functionality;
  int id;
  if(m_ButtonMenu!=NULL)
    for ( functionality=qfl.first(), id=0; functionality != 0; functionality=qfl.next(),++id )
      ((QButtonGroup*)m_ButtonMenu)->find(id)->setEnabled(functionality->IsAvailable());
}

void QmitkFctMediator::HideControls(bool hide)
{
  if(m_ControlStack==NULL) return;

  QWidget *controlStackParent = dynamic_cast<QWidget*>(m_ControlStack->parent());
  if(controlStackParent==NULL) return;

  if(hide)
    controlStackParent->hide();
  else
    controlStackParent->show();
}

void QmitkFctMediator::HideMenu(bool hide)
{
  if(m_ButtonMenu==NULL) return;

  if(hide)
    m_ButtonMenu->hide();
  else
    m_ButtonMenu->show();
}

int QmitkFctMediator::GetActiveFunctionalityId() const
{
  return m_CurrentFunctionality;
}

QmitkFunctionality* QmitkFctMediator::GetActiveFunctionality()
{
  return qfl.at(m_CurrentFunctionality);
}

QmitkFunctionality* QmitkFctMediator::GetFunctionalityById(int id)
{
  return qfl.at(id);
}

unsigned int QmitkFctMediator::GetFunctionalityCount()
{
  return m_NumOfFuncs;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *  containers/btree/test_btree.cpp
 *
 *  A very basic test
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

#include <iostream>

#include <stxxl/bits/containers/btree/btree.h>
#include <stxxl/timer>

struct comp_type : public std::less<int>
{
    static int max_value()
    {
        return (std::numeric_limits<int>::max)();
    }
};

typedef stxxl::btree::btree<int, double, comp_type, 4096, 4096, stxxl::SR> btree_type;

std::ostream & operator << (std::ostream & o, const std::pair<int, double> & obj)
{
    o << obj.first << " " << obj.second;
    return o;
}

#define node_cache_size (25 * 1024 * 1024)
#define leaf_cache_size (25 * 1024 * 1024)

int main(int argc, char * argv[])
{
    if (argc < 2)
    {
        STXXL_MSG("Usage: " << argv[0] << " #ins");
        return 1;
    }

    btree_type BTree1(node_cache_size, leaf_cache_size);

    unsigned nins = atoi(argv[1]);
    if (nins < 100)
        nins = 100;

    stxxl::random_number32 rnd;

    // .begin() .end() test
    BTree1[10] = 100.;
    btree_type::iterator begin = BTree1.begin();
    btree_type::iterator end = BTree1.end();
    assert(begin == BTree1.begin());
    BTree1[5] = 50.;
    btree_type::iterator nbegin = BTree1.begin();
    btree_type::iterator nend = BTree1.end();
    assert(nbegin == BTree1.begin());
    assert(begin != nbegin);
    assert(end == nend);
    assert(begin != end);
    assert(nbegin != end);
    assert(begin->first == 10);
    assert(begin->second == 100);
    assert(nbegin->first == 5);
    assert(nbegin->second == 50);

    BTree1[10] = 200.;
    assert(begin->second == 200.);

    btree_type::iterator it = BTree1.find(5);
    assert(it != BTree1.end());
    assert(it->first == 5);
    assert(it->second == 50.);
    it = BTree1.find(6);
    assert(it == BTree1.end());
    it = BTree1.find(1000);
    assert(it == BTree1.end());

    int f = BTree1.erase(5);
    assert(f == 1);
    f = BTree1.erase(6);
    assert(f == 0);
    f = BTree1.erase(5);
    assert(f == 0);

    assert(BTree1.count(10) == 1);
    assert(BTree1.count(5) == 0);

    it = BTree1.insert(BTree1.begin(), std::pair<int, double>(7, 70.));
    assert(it->second == 70.);
    assert(BTree1.size() == 2);
    it = BTree1.insert(BTree1.begin(), std::pair<int, double>(10, 300.));
    assert(it->second == 200.);
    assert(BTree1.size() == 2);

    // test lower_bound

    it = BTree1.lower_bound(6);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.lower_bound(7);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.lower_bound(8);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.lower_bound(11);
    assert(it == BTree1.end());

    // test upper_bound

    it = BTree1.upper_bound(6);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.upper_bound(7);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.upper_bound(8);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.upper_bound(10);
    assert(it == BTree1.end());

    it = BTree1.upper_bound(11);
    assert(it == BTree1.end());

    // test equal_range

    std::pair<btree_type::iterator, btree_type::iterator> it_pair = BTree1.equal_range(1);
    assert(BTree1.find(7) == it_pair.first);
    assert(BTree1.find(7) == it_pair.second);

    it_pair = BTree1.equal_range(7);
    assert(BTree1.find(7) == it_pair.first);
    assert(BTree1.find(10) == it_pair.second);

    it_pair = BTree1.equal_range(8);
    assert(BTree1.find(10) == it_pair.first);
    assert(BTree1.find(10) == it_pair.second);

    it_pair = BTree1.equal_range(10);
    assert(BTree1.find(10) == it_pair.first);
    assert(BTree1.end() == it_pair.second);

    it_pair = BTree1.equal_range(11);
    assert(BTree1.end() == it_pair.first);
    assert(BTree1.end() == it_pair.second);

    //

    it = BTree1.lower_bound(0);
    BTree1.erase(it);
    assert(BTree1.size() == 1);

    BTree1.clear();
    assert(BTree1.size() == 0);

    for (unsigned int i = 0; i < nins / 2; ++i)
    {
        BTree1[rnd() % nins] = 10.1;
    }
    STXXL_MSG("Size of map: " << BTree1.size());

    BTree1.clear();

    for (unsigned int i = 0; i < nins / 2; ++i)
    {
        BTree1[rnd() % nins] = 10.1;
    }

    STXXL_MSG("Size of map: " << BTree1.size());

    btree_type BTree2(comp_type(), node_cache_size, leaf_cache_size);

    STXXL_MSG("Construction of BTree3 from BTree1 that has " << BTree1.size() << " elements");
    btree_type BTree3(BTree1.begin(), BTree1.end(), comp_type(), node_cache_size, leaf_cache_size);

    assert(BTree3 == BTree1);

    STXXL_MSG("Bulk construction of BTree4 from BTree1 that has " << BTree1.size() << " elements");
    btree_type BTree4(BTree1.begin(), BTree1.end(), comp_type(), node_cache_size, leaf_cache_size, true);

    STXXL_MSG("Size of BTree1: " << BTree1.size());
    STXXL_MSG("Size of BTree4: " << BTree4.size());

    assert(BTree4 == BTree1);
    assert(BTree3 == BTree4);

    BTree4.begin()->second = 0;
    assert(BTree3 != BTree4);
    assert(BTree4 < BTree3);

    BTree4.begin()->second = 1000;
    assert(BTree4 > BTree3);

    assert(BTree3 != BTree4);

    it = BTree4.begin();
    ++it;
    STXXL_MSG("Size of Btree4 before erase: " << BTree4.size());
    BTree4.erase(it, BTree4.end());
    STXXL_MSG("Size of Btree4 after erase: " << BTree4.size());
    assert(BTree4.size() == 1);

    STXXL_MSG("Size of Btree1 before erase: " << BTree1.size());
    BTree1.erase(BTree1.begin(), BTree1.end());
    STXXL_MSG("Size of Btree1 after erase: " << BTree1.size());
    assert(BTree1.empty());

    // a copy of BTree3
    btree_type BTree5(BTree3.begin(), BTree3.end(), comp_type(), node_cache_size, leaf_cache_size, true);
    assert(BTree5 == BTree3);

    btree_type::iterator b3 = BTree3.begin();
    btree_type::iterator b4 = BTree4.begin();
    btree_type::iterator e3 = BTree3.end();
    btree_type::iterator e4 = BTree4.end();

    STXXL_MSG("Testing swapping operation (std::swap)");
    std::swap(BTree4, BTree3);
    assert(b3 == BTree4.begin());
    assert(b4 == BTree3.begin());
    assert(e3 == BTree4.end());
    assert(e4 == BTree3.end());

    assert(BTree5 == BTree4);
    assert(BTree5 != BTree3);

    btree_type::const_iterator cb = BTree3.begin();
    btree_type::const_iterator ce = BTree3.end();
    const btree_type & CBTree3 = BTree3;
    cb = CBTree3.begin();
    b3 == cb;
    b3 != cb;
    cb == b3;
    cb != b3;
    ce = CBTree3.end();
    btree_type::const_iterator cit = CBTree3.find(0);
    cit = CBTree3.lower_bound(0);
    cit = CBTree3.upper_bound(0);

    std::pair<btree_type::const_iterator, btree_type::const_iterator> cit_pair = CBTree3.equal_range(1);

    assert(CBTree3.max_size() >= CBTree3.size());

    CBTree3.key_comp();
    CBTree3.value_comp();

    double sum;

    STXXL_MSG(*stxxl::stats::get_instance());

    stxxl::timer Timer2;
    Timer2.start();
    cit = BTree5.begin();
    for ( ; cit != BTree5.end(); ++cit)
        sum += cit->second;

    Timer2.stop();
    STXXL_MSG("Scanning with const iterator: " << Timer2.mseconds() << " msec");

    STXXL_MSG(*stxxl::stats::get_instance());

    stxxl::timer Timer1;
    Timer1.start();
    it = BTree5.begin();
    for ( ; it != BTree5.end(); ++it)
        sum += it->second;

    Timer1.stop();
    STXXL_MSG("Scanning with non const iterator: " << Timer1.mseconds() << " msec");

    STXXL_MSG(*stxxl::stats::get_instance());

    BTree5.disable_prefetching();
    BTree5.enable_prefetching();
    BTree5.prefetching_enabled();
    assert(BTree5.prefetching_enabled());

    STXXL_MSG("All tests passed successfully");

    return 0;
}
<commit_msg>initialize a dummy variable to avoid warnings<commit_after>/***************************************************************************
 *  containers/btree/test_btree.cpp
 *
 *  A very basic test
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

#include <iostream>

#include <stxxl/bits/containers/btree/btree.h>
#include <stxxl/timer>

struct comp_type : public std::less<int>
{
    static int max_value()
    {
        return (std::numeric_limits<int>::max)();
    }
};

typedef stxxl::btree::btree<int, double, comp_type, 4096, 4096, stxxl::SR> btree_type;

std::ostream & operator << (std::ostream & o, const std::pair<int, double> & obj)
{
    o << obj.first << " " << obj.second;
    return o;
}

#define node_cache_size (25 * 1024 * 1024)
#define leaf_cache_size (25 * 1024 * 1024)

int main(int argc, char * argv[])
{
    if (argc < 2)
    {
        STXXL_MSG("Usage: " << argv[0] << " #ins");
        return 1;
    }

    btree_type BTree1(node_cache_size, leaf_cache_size);

    unsigned nins = atoi(argv[1]);
    if (nins < 100)
        nins = 100;

    stxxl::random_number32 rnd;

    // .begin() .end() test
    BTree1[10] = 100.;
    btree_type::iterator begin = BTree1.begin();
    btree_type::iterator end = BTree1.end();
    assert(begin == BTree1.begin());
    BTree1[5] = 50.;
    btree_type::iterator nbegin = BTree1.begin();
    btree_type::iterator nend = BTree1.end();
    assert(nbegin == BTree1.begin());
    assert(begin != nbegin);
    assert(end == nend);
    assert(begin != end);
    assert(nbegin != end);
    assert(begin->first == 10);
    assert(begin->second == 100);
    assert(nbegin->first == 5);
    assert(nbegin->second == 50);

    BTree1[10] = 200.;
    assert(begin->second == 200.);

    btree_type::iterator it = BTree1.find(5);
    assert(it != BTree1.end());
    assert(it->first == 5);
    assert(it->second == 50.);
    it = BTree1.find(6);
    assert(it == BTree1.end());
    it = BTree1.find(1000);
    assert(it == BTree1.end());

    int f = BTree1.erase(5);
    assert(f == 1);
    f = BTree1.erase(6);
    assert(f == 0);
    f = BTree1.erase(5);
    assert(f == 0);

    assert(BTree1.count(10) == 1);
    assert(BTree1.count(5) == 0);

    it = BTree1.insert(BTree1.begin(), std::pair<int, double>(7, 70.));
    assert(it->second == 70.);
    assert(BTree1.size() == 2);
    it = BTree1.insert(BTree1.begin(), std::pair<int, double>(10, 300.));
    assert(it->second == 200.);
    assert(BTree1.size() == 2);

    // test lower_bound

    it = BTree1.lower_bound(6);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.lower_bound(7);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.lower_bound(8);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.lower_bound(11);
    assert(it == BTree1.end());

    // test upper_bound

    it = BTree1.upper_bound(6);
    assert(it != BTree1.end());
    assert(it->first == 7);

    it = BTree1.upper_bound(7);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.upper_bound(8);
    assert(it != BTree1.end());
    assert(it->first == 10);

    it = BTree1.upper_bound(10);
    assert(it == BTree1.end());

    it = BTree1.upper_bound(11);
    assert(it == BTree1.end());

    // test equal_range

    std::pair<btree_type::iterator, btree_type::iterator> it_pair = BTree1.equal_range(1);
    assert(BTree1.find(7) == it_pair.first);
    assert(BTree1.find(7) == it_pair.second);

    it_pair = BTree1.equal_range(7);
    assert(BTree1.find(7) == it_pair.first);
    assert(BTree1.find(10) == it_pair.second);

    it_pair = BTree1.equal_range(8);
    assert(BTree1.find(10) == it_pair.first);
    assert(BTree1.find(10) == it_pair.second);

    it_pair = BTree1.equal_range(10);
    assert(BTree1.find(10) == it_pair.first);
    assert(BTree1.end() == it_pair.second);

    it_pair = BTree1.equal_range(11);
    assert(BTree1.end() == it_pair.first);
    assert(BTree1.end() == it_pair.second);

    //

    it = BTree1.lower_bound(0);
    BTree1.erase(it);
    assert(BTree1.size() == 1);

    BTree1.clear();
    assert(BTree1.size() == 0);

    for (unsigned int i = 0; i < nins / 2; ++i)
    {
        BTree1[rnd() % nins] = 10.1;
    }
    STXXL_MSG("Size of map: " << BTree1.size());

    BTree1.clear();

    for (unsigned int i = 0; i < nins / 2; ++i)
    {
        BTree1[rnd() % nins] = 10.1;
    }

    STXXL_MSG("Size of map: " << BTree1.size());

    btree_type BTree2(comp_type(), node_cache_size, leaf_cache_size);

    STXXL_MSG("Construction of BTree3 from BTree1 that has " << BTree1.size() << " elements");
    btree_type BTree3(BTree1.begin(), BTree1.end(), comp_type(), node_cache_size, leaf_cache_size);

    assert(BTree3 == BTree1);

    STXXL_MSG("Bulk construction of BTree4 from BTree1 that has " << BTree1.size() << " elements");
    btree_type BTree4(BTree1.begin(), BTree1.end(), comp_type(), node_cache_size, leaf_cache_size, true);

    STXXL_MSG("Size of BTree1: " << BTree1.size());
    STXXL_MSG("Size of BTree4: " << BTree4.size());

    assert(BTree4 == BTree1);
    assert(BTree3 == BTree4);

    BTree4.begin()->second = 0;
    assert(BTree3 != BTree4);
    assert(BTree4 < BTree3);

    BTree4.begin()->second = 1000;
    assert(BTree4 > BTree3);

    assert(BTree3 != BTree4);

    it = BTree4.begin();
    ++it;
    STXXL_MSG("Size of Btree4 before erase: " << BTree4.size());
    BTree4.erase(it, BTree4.end());
    STXXL_MSG("Size of Btree4 after erase: " << BTree4.size());
    assert(BTree4.size() == 1);

    STXXL_MSG("Size of Btree1 before erase: " << BTree1.size());
    BTree1.erase(BTree1.begin(), BTree1.end());
    STXXL_MSG("Size of Btree1 after erase: " << BTree1.size());
    assert(BTree1.empty());

    // a copy of BTree3
    btree_type BTree5(BTree3.begin(), BTree3.end(), comp_type(), node_cache_size, leaf_cache_size, true);
    assert(BTree5 == BTree3);

    btree_type::iterator b3 = BTree3.begin();
    btree_type::iterator b4 = BTree4.begin();
    btree_type::iterator e3 = BTree3.end();
    btree_type::iterator e4 = BTree4.end();

    STXXL_MSG("Testing swapping operation (std::swap)");
    std::swap(BTree4, BTree3);
    assert(b3 == BTree4.begin());
    assert(b4 == BTree3.begin());
    assert(e3 == BTree4.end());
    assert(e4 == BTree3.end());

    assert(BTree5 == BTree4);
    assert(BTree5 != BTree3);

    btree_type::const_iterator cb = BTree3.begin();
    btree_type::const_iterator ce = BTree3.end();
    const btree_type & CBTree3 = BTree3;
    cb = CBTree3.begin();
    b3 == cb;
    b3 != cb;
    cb == b3;
    cb != b3;
    ce = CBTree3.end();
    btree_type::const_iterator cit = CBTree3.find(0);
    cit = CBTree3.lower_bound(0);
    cit = CBTree3.upper_bound(0);

    std::pair<btree_type::const_iterator, btree_type::const_iterator> cit_pair = CBTree3.equal_range(1);

    assert(CBTree3.max_size() >= CBTree3.size());

    CBTree3.key_comp();
    CBTree3.value_comp();

    double sum = 0.0;

    STXXL_MSG(*stxxl::stats::get_instance());

    stxxl::timer Timer2;
    Timer2.start();
    cit = BTree5.begin();
    for ( ; cit != BTree5.end(); ++cit)
        sum += cit->second;

    Timer2.stop();
    STXXL_MSG("Scanning with const iterator: " << Timer2.mseconds() << " msec");

    STXXL_MSG(*stxxl::stats::get_instance());

    stxxl::timer Timer1;
    Timer1.start();
    it = BTree5.begin();
    for ( ; it != BTree5.end(); ++it)
        sum += it->second;

    Timer1.stop();
    STXXL_MSG("Scanning with non const iterator: " << Timer1.mseconds() << " msec");

    STXXL_MSG(*stxxl::stats::get_instance());

    BTree5.disable_prefetching();
    BTree5.enable_prefetching();
    BTree5.prefetching_enabled();
    assert(BTree5.prefetching_enabled());

    STXXL_MSG("All tests passed successfully");

    return 0;
}
<|endoftext|>


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

#include "content/plugin/npobject_util.h"

#include "base/string_util.h"
#include "content/common/plugin_messages.h"
#include "content/plugin/npobject_proxy.h"
#include "content/plugin/plugin_channel_base.h"
#include "third_party/npapi/bindings/nphostapi.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "webkit/plugins/npapi/plugin_host.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebBindings;

// true if the current process is a plugin process, false if it's a renderer
// process.
static bool g_plugin_process;

namespace {
// The next 7 functions are called by the plugin code when it's using the
// NPObject.  Plugins always ignore the functions in NPClass (except allocate
// and deallocate), and instead just use the function pointers that were
// passed in NPInitialize.
// When the renderer interacts with an NPObject from the plugin, it of course
// uses the function pointers in its NPClass structure.
static bool NPN_HasMethodPatch(NPP npp,
                               NPObject *npobj,
                               NPIdentifier methodName) {
  return NPObjectProxy::NPHasMethod(npobj, methodName);
}

static bool NPN_InvokePatch(NPP npp, NPObject *npobj,
                            NPIdentifier methodName,
                            const NPVariant *args,
                            uint32_t argCount,
                            NPVariant *result) {
  return NPObjectProxy::NPInvokePrivate(npp, npobj, false, methodName, args,
                                        argCount, result);
}

static bool NPN_InvokeDefaultPatch(NPP npp,
                                   NPObject *npobj,
                                   const NPVariant *args,
                                   uint32_t argCount,
                                   NPVariant *result) {
  return NPObjectProxy::NPInvokePrivate(npp, npobj, true, 0, args, argCount,
                                        result);
}

static bool NPN_HasPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName) {
  return NPObjectProxy::NPHasProperty(npobj, propertyName);
}

static bool NPN_GetPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName,
                                 NPVariant *result) {
  return NPObjectProxy::NPGetProperty(npobj, propertyName, result);
}

static bool NPN_SetPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName,
                                 const NPVariant *value) {
  return NPObjectProxy::NPSetProperty(npobj, propertyName, value);
}

static bool NPN_RemovePropertyPatch(NPP npp,
                                    NPObject *npobj,
                                    NPIdentifier propertyName) {
  return NPObjectProxy::NPRemoveProperty(npobj, propertyName);
}

static bool NPN_EvaluatePatch(NPP npp,
                              NPObject *npobj,
                              NPString *script,
                              NPVariant *result) {
  return NPObjectProxy::NPNEvaluate(npp, npobj, script, result);
}

static void NPN_SetExceptionPatch(NPObject *obj, const NPUTF8 *message) {
  std::string message_str(message);
  if (IsPluginProcess()) {
    PluginChannelBase* renderer_channel =
        PluginChannelBase::GetCurrentChannel();
    if (renderer_channel)
      renderer_channel->Send(new PluginHostMsg_SetException(message_str));
  } else {
    WebBindings::setException(obj, message_str.c_str());
  }
}

static bool NPN_EnumeratePatch(NPP npp, NPObject *obj,
                               NPIdentifier **identifier, uint32_t *count) {
  return NPObjectProxy::NPNEnumerate(obj, identifier, count);
}

// The overrided table of functions provided to the plugin.
NPNetscapeFuncs *GetHostFunctions() {
  static bool init = false;
  static NPNetscapeFuncs host_funcs;
  if (init)
    return &host_funcs;

  memset(&host_funcs, 0, sizeof(host_funcs));
  host_funcs.invoke = NPN_InvokePatch;
  host_funcs.invokeDefault = NPN_InvokeDefaultPatch;
  host_funcs.evaluate = NPN_EvaluatePatch;
  host_funcs.getproperty = NPN_GetPropertyPatch;
  host_funcs.setproperty = NPN_SetPropertyPatch;
  host_funcs.removeproperty = NPN_RemovePropertyPatch;
  host_funcs.hasproperty = NPN_HasPropertyPatch;
  host_funcs.hasmethod = NPN_HasMethodPatch;
  host_funcs.setexception = NPN_SetExceptionPatch;
  host_funcs.enumerate = NPN_EnumeratePatch;

  init = true;
  return &host_funcs;
}

}

void PatchNPNFunctions() {
  g_plugin_process = true;
  NPNetscapeFuncs* funcs = GetHostFunctions();
  webkit::npapi::PluginHost::Singleton()->PatchNPNetscapeFuncs(funcs);
}

bool IsPluginProcess() {
  return g_plugin_process;
}

void CreateNPIdentifierParam(NPIdentifier id, NPIdentifier_Param* param) {
  param->identifier = id;
}

NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param) {
  return param.identifier;
}

void CreateNPVariantParam(const NPVariant& variant,
                          PluginChannelBase* channel,
                          NPVariant_Param* param,
                          bool release,
                          gfx::NativeViewId containing_window,
                          const GURL& page_url) {
  switch (variant.type) {
    case NPVariantType_Void:
      param->type = NPVARIANT_PARAM_VOID;
      break;
    case NPVariantType_Null:
      param->type = NPVARIANT_PARAM_NULL;
      break;
    case NPVariantType_Bool:
      param->type = NPVARIANT_PARAM_BOOL;
      param->bool_value = variant.value.boolValue;
      break;
    case NPVariantType_Int32:
      param->type = NPVARIANT_PARAM_INT;
      param->int_value = variant.value.intValue;
      break;
    case NPVariantType_Double:
      param->type = NPVARIANT_PARAM_DOUBLE;
      param->double_value = variant.value.doubleValue;
      break;
    case NPVariantType_String:
      param->type = NPVARIANT_PARAM_STRING;
      if (variant.value.stringValue.UTF8Length) {
        param->string_value.assign(variant.value.stringValue.UTF8Characters,
                                   variant.value.stringValue.UTF8Length);
      }
      break;
    case NPVariantType_Object: {
      if (variant.value.objectValue->_class == NPObjectProxy::npclass()) {
        param->type = NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID;
        NPObjectProxy* proxy =
            NPObjectProxy::GetProxy(variant.value.objectValue);
        DCHECK(proxy);
        param->npobject_routing_id = proxy->route_id();
        // Don't release, because our original variant is the same as our proxy.
        release = false;
      } else {
        // The channel could be NULL if there was a channel error. The caller's
        // Send call will fail anyways.
        if (channel) {
          // NPObjectStub adds its own reference to the NPObject it owns, so if
          // we were supposed to release the corresponding variant
          // (release==true), we should still do that.
          param->type = NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID;
          int route_id = channel->GetExistingRouteForNPObjectStub(
              variant.value.objectValue);
          if (route_id != MSG_ROUTING_NONE) {
            param->npobject_routing_id = route_id;
          } else {
            route_id = channel->GenerateRouteID();
            new NPObjectStub(
                variant.value.objectValue, channel, route_id,
                containing_window, page_url);
            param->npobject_routing_id = route_id;
          }
        } else {
          param->type = NPVARIANT_PARAM_VOID;
        }
      }
      break;
    }
    default:
      NOTREACHED();
  }

  if (release)
    WebBindings::releaseVariantValue(const_cast<NPVariant*>(&variant));
}

bool CreateNPVariant(const NPVariant_Param& param,
                     PluginChannelBase* channel,
                     NPVariant* result,
                     gfx::NativeViewId containing_window,
                     const GURL& page_url) {
  NPObject* object = NULL;
  switch (param.type) {
    case NPVARIANT_PARAM_VOID:
      result->type = NPVariantType_Void;
      break;
    case NPVARIANT_PARAM_NULL:
      result->type = NPVariantType_Null;
      break;
    case NPVARIANT_PARAM_BOOL:
      result->type = NPVariantType_Bool;
      result->value.boolValue = param.bool_value;
      break;
    case NPVARIANT_PARAM_INT:
      result->type = NPVariantType_Int32;
      result->value.intValue = param.int_value;
      break;
    case NPVARIANT_PARAM_DOUBLE:
      result->type = NPVariantType_Double;
      result->value.doubleValue = param.double_value;
      break;
    case NPVARIANT_PARAM_STRING: {
      result->type = NPVariantType_String;
      void* buffer = malloc(param.string_value.size());
      size_t size = param.string_value.size();
      result->value.stringValue.UTF8Characters = static_cast<NPUTF8*>(buffer);
      memcpy(buffer, param.string_value.c_str(), size);
      result->value.stringValue.UTF8Length = static_cast<int>(size);
      break;
    }
    case NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID:
      result->type = NPVariantType_Object;
      object = channel->GetExistingNPObjectProxy(param.npobject_routing_id);
      if (object) {
        WebBindings::retainObject(object);
        result->value.objectValue = object;
      } else {
        result->value.objectValue =
            object = NPObjectProxy::Create(channel,
                                           param.npobject_routing_id,
                                           containing_window,
                                           page_url);
        result->value.objectValue = object;
      }
      break;
    case NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID: {
      NPObjectBase* npobject_base =
          channel->GetNPObjectListenerForRoute(param.npobject_routing_id);
      if (!npobject_base) {
        DLOG(WARNING) << "Invalid routing id passed in"
                      << param.npobject_routing_id;
        return false;
      }

      DCHECK(npobject_base->GetUnderlyingNPObject() != NULL);

      result->type = NPVariantType_Object;
      result->value.objectValue = npobject_base->GetUnderlyingNPObject();
      WebBindings::retainObject(result->value.objectValue);
      break;
    }
    default:
      NOTREACHED();
  }
  return true;
}
<commit_msg>Simplify some code in CreateNPVariant()<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/plugin/npobject_util.h"

#include "base/string_util.h"
#include "content/common/plugin_messages.h"
#include "content/plugin/npobject_proxy.h"
#include "content/plugin/plugin_channel_base.h"
#include "third_party/npapi/bindings/nphostapi.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "webkit/plugins/npapi/plugin_host.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebBindings;

// true if the current process is a plugin process, false if it's a renderer
// process.
static bool g_plugin_process;

namespace {
// The next 7 functions are called by the plugin code when it's using the
// NPObject.  Plugins always ignore the functions in NPClass (except allocate
// and deallocate), and instead just use the function pointers that were
// passed in NPInitialize.
// When the renderer interacts with an NPObject from the plugin, it of course
// uses the function pointers in its NPClass structure.
static bool NPN_HasMethodPatch(NPP npp,
                               NPObject *npobj,
                               NPIdentifier methodName) {
  return NPObjectProxy::NPHasMethod(npobj, methodName);
}

static bool NPN_InvokePatch(NPP npp, NPObject *npobj,
                            NPIdentifier methodName,
                            const NPVariant *args,
                            uint32_t argCount,
                            NPVariant *result) {
  return NPObjectProxy::NPInvokePrivate(npp, npobj, false, methodName, args,
                                        argCount, result);
}

static bool NPN_InvokeDefaultPatch(NPP npp,
                                   NPObject *npobj,
                                   const NPVariant *args,
                                   uint32_t argCount,
                                   NPVariant *result) {
  return NPObjectProxy::NPInvokePrivate(npp, npobj, true, 0, args, argCount,
                                        result);
}

static bool NPN_HasPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName) {
  return NPObjectProxy::NPHasProperty(npobj, propertyName);
}

static bool NPN_GetPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName,
                                 NPVariant *result) {
  return NPObjectProxy::NPGetProperty(npobj, propertyName, result);
}

static bool NPN_SetPropertyPatch(NPP npp,
                                 NPObject *npobj,
                                 NPIdentifier propertyName,
                                 const NPVariant *value) {
  return NPObjectProxy::NPSetProperty(npobj, propertyName, value);
}

static bool NPN_RemovePropertyPatch(NPP npp,
                                    NPObject *npobj,
                                    NPIdentifier propertyName) {
  return NPObjectProxy::NPRemoveProperty(npobj, propertyName);
}

static bool NPN_EvaluatePatch(NPP npp,
                              NPObject *npobj,
                              NPString *script,
                              NPVariant *result) {
  return NPObjectProxy::NPNEvaluate(npp, npobj, script, result);
}

static void NPN_SetExceptionPatch(NPObject *obj, const NPUTF8 *message) {
  std::string message_str(message);
  if (IsPluginProcess()) {
    PluginChannelBase* renderer_channel =
        PluginChannelBase::GetCurrentChannel();
    if (renderer_channel)
      renderer_channel->Send(new PluginHostMsg_SetException(message_str));
  } else {
    WebBindings::setException(obj, message_str.c_str());
  }
}

static bool NPN_EnumeratePatch(NPP npp, NPObject *obj,
                               NPIdentifier **identifier, uint32_t *count) {
  return NPObjectProxy::NPNEnumerate(obj, identifier, count);
}

// The overrided table of functions provided to the plugin.
NPNetscapeFuncs *GetHostFunctions() {
  static bool init = false;
  static NPNetscapeFuncs host_funcs;
  if (init)
    return &host_funcs;

  memset(&host_funcs, 0, sizeof(host_funcs));
  host_funcs.invoke = NPN_InvokePatch;
  host_funcs.invokeDefault = NPN_InvokeDefaultPatch;
  host_funcs.evaluate = NPN_EvaluatePatch;
  host_funcs.getproperty = NPN_GetPropertyPatch;
  host_funcs.setproperty = NPN_SetPropertyPatch;
  host_funcs.removeproperty = NPN_RemovePropertyPatch;
  host_funcs.hasproperty = NPN_HasPropertyPatch;
  host_funcs.hasmethod = NPN_HasMethodPatch;
  host_funcs.setexception = NPN_SetExceptionPatch;
  host_funcs.enumerate = NPN_EnumeratePatch;

  init = true;
  return &host_funcs;
}

}

void PatchNPNFunctions() {
  g_plugin_process = true;
  NPNetscapeFuncs* funcs = GetHostFunctions();
  webkit::npapi::PluginHost::Singleton()->PatchNPNetscapeFuncs(funcs);
}

bool IsPluginProcess() {
  return g_plugin_process;
}

void CreateNPIdentifierParam(NPIdentifier id, NPIdentifier_Param* param) {
  param->identifier = id;
}

NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param) {
  return param.identifier;
}

void CreateNPVariantParam(const NPVariant& variant,
                          PluginChannelBase* channel,
                          NPVariant_Param* param,
                          bool release,
                          gfx::NativeViewId containing_window,
                          const GURL& page_url) {
  switch (variant.type) {
    case NPVariantType_Void:
      param->type = NPVARIANT_PARAM_VOID;
      break;
    case NPVariantType_Null:
      param->type = NPVARIANT_PARAM_NULL;
      break;
    case NPVariantType_Bool:
      param->type = NPVARIANT_PARAM_BOOL;
      param->bool_value = variant.value.boolValue;
      break;
    case NPVariantType_Int32:
      param->type = NPVARIANT_PARAM_INT;
      param->int_value = variant.value.intValue;
      break;
    case NPVariantType_Double:
      param->type = NPVARIANT_PARAM_DOUBLE;
      param->double_value = variant.value.doubleValue;
      break;
    case NPVariantType_String:
      param->type = NPVARIANT_PARAM_STRING;
      if (variant.value.stringValue.UTF8Length) {
        param->string_value.assign(variant.value.stringValue.UTF8Characters,
                                   variant.value.stringValue.UTF8Length);
      }
      break;
    case NPVariantType_Object: {
      if (variant.value.objectValue->_class == NPObjectProxy::npclass()) {
        param->type = NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID;
        NPObjectProxy* proxy =
            NPObjectProxy::GetProxy(variant.value.objectValue);
        DCHECK(proxy);
        param->npobject_routing_id = proxy->route_id();
        // Don't release, because our original variant is the same as our proxy.
        release = false;
      } else {
        // The channel could be NULL if there was a channel error. The caller's
        // Send call will fail anyways.
        if (channel) {
          // NPObjectStub adds its own reference to the NPObject it owns, so if
          // we were supposed to release the corresponding variant
          // (release==true), we should still do that.
          param->type = NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID;
          int route_id = channel->GetExistingRouteForNPObjectStub(
              variant.value.objectValue);
          if (route_id != MSG_ROUTING_NONE) {
            param->npobject_routing_id = route_id;
          } else {
            route_id = channel->GenerateRouteID();
            new NPObjectStub(
                variant.value.objectValue, channel, route_id,
                containing_window, page_url);
            param->npobject_routing_id = route_id;
          }
        } else {
          param->type = NPVARIANT_PARAM_VOID;
        }
      }
      break;
    }
    default:
      NOTREACHED();
  }

  if (release)
    WebBindings::releaseVariantValue(const_cast<NPVariant*>(&variant));
}

bool CreateNPVariant(const NPVariant_Param& param,
                     PluginChannelBase* channel,
                     NPVariant* result,
                     gfx::NativeViewId containing_window,
                     const GURL& page_url) {
  switch (param.type) {
    case NPVARIANT_PARAM_VOID:
      result->type = NPVariantType_Void;
      break;
    case NPVARIANT_PARAM_NULL:
      result->type = NPVariantType_Null;
      break;
    case NPVARIANT_PARAM_BOOL:
      result->type = NPVariantType_Bool;
      result->value.boolValue = param.bool_value;
      break;
    case NPVARIANT_PARAM_INT:
      result->type = NPVariantType_Int32;
      result->value.intValue = param.int_value;
      break;
    case NPVARIANT_PARAM_DOUBLE:
      result->type = NPVariantType_Double;
      result->value.doubleValue = param.double_value;
      break;
    case NPVARIANT_PARAM_STRING: {
      result->type = NPVariantType_String;
      void* buffer = malloc(param.string_value.size());
      size_t size = param.string_value.size();
      result->value.stringValue.UTF8Characters = static_cast<NPUTF8*>(buffer);
      memcpy(buffer, param.string_value.c_str(), size);
      result->value.stringValue.UTF8Length = static_cast<int>(size);
      break;
    }
    case NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID: {
      result->type = NPVariantType_Object;
      NPObject* object =
          channel->GetExistingNPObjectProxy(param.npobject_routing_id);
      if (object) {
        WebBindings::retainObject(object);
        result->value.objectValue = object;
      } else {
        result->value.objectValue =
            NPObjectProxy::Create(channel,
                                  param.npobject_routing_id,
                                  containing_window,
                                  page_url);
      }
      break;
    }
    case NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID: {
      NPObjectBase* npobject_base =
          channel->GetNPObjectListenerForRoute(param.npobject_routing_id);
      if (!npobject_base) {
        DLOG(WARNING) << "Invalid routing id passed in"
                      << param.npobject_routing_id;
        return false;
      }

      DCHECK(npobject_base->GetUnderlyingNPObject() != NULL);

      result->type = NPVariantType_Object;
      result->value.objectValue = npobject_base->GetUnderlyingNPObject();
      WebBindings::retainObject(result->value.objectValue);
      break;
    }
    default:
      NOTREACHED();
  }
  return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPath.h"

static void make_bm(SkBitmap* bm, int width, int height, SkColor colors[2]) {
    bm->allocN32Pixels(width, height);
    SkCanvas canvas(*bm);
    SkPoint center = {SkIntToScalar(width)/2, SkIntToScalar(height)/2};
    SkScalar radius = 40;
    SkShader* shader = SkGradientShader::CreateRadial(center, radius, colors, nullptr, 2,
                                                      SkShader::kMirror_TileMode);
    SkPaint paint;
    paint.setShader(shader)->unref();
    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    canvas.drawPaint(paint);
    bm->setImmutable();
}

static void show_bm(SkCanvas* canvas, int width, int height, SkColor colors[2]) {
    SkBitmap bm;
    make_bm(&bm, width, height, colors);

    SkPaint paint;
    SkRect r;
    SkIRect ir;

    paint.setStyle(SkPaint::kStroke_Style);

    ir.set(0, 0, 128, 128);
    r.set(ir);

    canvas->save();
    canvas->clipRect(r);
    canvas->drawBitmap(bm, 0, 0, nullptr);
    canvas->restore();
    canvas->drawRect(r, paint);

    r.offset(SkIntToScalar(150), 0);
    // exercises extract bitmap, but not shader
    canvas->drawBitmapRect(bm, ir, r, nullptr);
    canvas->drawRect(r, paint);

    r.offset(SkIntToScalar(150), 0);
    // exercises bitmapshader
    canvas->drawBitmapRect(bm, r, nullptr);
    canvas->drawRect(r, paint);
}

class VeryLargeBitmapGM : public skiagm::GM {
public:
    VeryLargeBitmapGM() {}

protected:
    SkString onShortName() override {
        return SkString("verylargebitmap");
    }

    SkISize onISize() override {
        return SkISize::Make(500, 600);
    }

    void onDraw(SkCanvas* canvas) override {
        int veryBig = 65*1024; // 64K < size
        int big = 33*1024;     // 32K < size < 64K
        // smaller than many max texture sizes, but large enough to gpu-tile for memory reasons.
        int medium = 5*1024;
        int small = 150;

        SkColor colors[2];

        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
        colors[0] = SK_ColorRED;
        colors[1] = SK_ColorGREEN;
        show_bm(canvas, small, small, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorBLUE;
        colors[1] = SK_ColorMAGENTA;
        show_bm(canvas, big, small, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorMAGENTA;
        colors[1] = SK_ColorYELLOW;
        show_bm(canvas, medium, medium, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorGREEN;
        colors[1] = SK_ColorYELLOW;
        // as of this writing, the raster code will fail to draw the scaled version
        // since it has a 64K limit on x,y coordinates... (but gpu should succeed)
        show_bm(canvas, veryBig, small, colors);
    }

private:
    typedef skiagm::GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static skiagm::GM* MyFactory(void*) { return new VeryLargeBitmapGM; }
static skiagm::GMRegistry reg(MyFactory);
<commit_msg>switch over to using images<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPath.h"
#include "SkSurface.h"

static SkImage* make_image(int width, int height, SkColor colors[2]) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(width, height));

    const SkPoint center = { SkIntToScalar(width)/2, SkIntToScalar(height)/2 };
    const SkScalar radius = 40;
    SkShader* shader = SkGradientShader::CreateRadial(center, radius, colors, nullptr, 2,
                                                      SkShader::kMirror_TileMode);
    SkPaint paint;
    paint.setShader(shader)->unref();
    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    surface->getCanvas()->drawPaint(paint);
    return surface->newImageSnapshot();
}

static void show_image(SkCanvas* canvas, int width, int height, SkColor colors[2]) {
    SkAutoTUnref<SkImage> image(make_image(width, height, colors));

    SkPaint paint;
    SkRect r;
    SkIRect ir;

    paint.setStyle(SkPaint::kStroke_Style);

    ir.set(0, 0, 128, 128);
    r.set(ir);

    canvas->save();
    canvas->clipRect(r);
    canvas->drawImage(image, 0, 0, nullptr);
    canvas->restore();
    canvas->drawRect(r, paint);

    r.offset(SkIntToScalar(150), 0);
    canvas->drawImageRect(image, ir, r, nullptr);
    canvas->drawRect(r, paint);

    r.offset(SkIntToScalar(150), 0);
    canvas->drawImageRect(image, r, nullptr);
    canvas->drawRect(r, paint);
}

class VeryLargeBitmapGM : public skiagm::GM {
public:
    VeryLargeBitmapGM() {}

protected:
    SkString onShortName() override {
        return SkString("verylargebitmap");
    }

    SkISize onISize() override {
        return SkISize::Make(500, 600);
    }

    void onDraw(SkCanvas* canvas) override {
        int veryBig = 65*1024; // 64K < size
        int big = 33*1024;     // 32K < size < 64K
        // smaller than many max texture sizes, but large enough to gpu-tile for memory reasons.
        int medium = 5*1024;
        int small = 150;

        SkColor colors[2];

        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
        colors[0] = SK_ColorRED;
        colors[1] = SK_ColorGREEN;
        show_image(canvas, small, small, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorBLUE;
        colors[1] = SK_ColorMAGENTA;
        show_image(canvas, big, small, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorMAGENTA;
        colors[1] = SK_ColorYELLOW;
        show_image(canvas, medium, medium, colors);
        canvas->translate(0, SkIntToScalar(150));

        colors[0] = SK_ColorGREEN;
        colors[1] = SK_ColorYELLOW;
        // as of this writing, the raster code will fail to draw the scaled version
        // since it has a 64K limit on x,y coordinates... (but gpu should succeed)
        show_image(canvas, veryBig, small, colors);
    }

private:
    typedef skiagm::GM INHERITED;
};
DEF_GM( return new VeryLargeBitmapGM; )

<|endoftext|>


<commit_before><commit_msg>Planning: fix a bug with smart lane-change.<commit_after><|endoftext|>


<commit_before>#include "UnrealCVPrivate.h"
#include "UE4CVCommands.h"
#include "UE4CVServer.h"

void UE4CVCommands::RegisterCommandsPlugin()
{
	FDispatcherDelegate Cmd;
	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::GetPort);
	CommandDispatcher->BindCommand("vget /unrealcv/port", Cmd, "Get port from the plugin listening to");

	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::SetPort);
	CommandDispatcher->BindCommand("vset /unrealcv/port [uint]", Cmd, "Set port the plugin listening to");

	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::GetUnrealCVStatus);
	CommandDispatcher->BindCommand("vget /unrealcv/status", Cmd, "Get camera location");
}

FExecStatus UE4CVCommands::GetPort(const TArray<FString>& Args)
{
	FString Msg = FString::Printf(TEXT("%d"), FUE4CVServer::Get().NetworkManager->PortNum);
	return FExecStatus::OK(Msg);
	// return FExecStatus::InvalidArgument;
}

FExecStatus UE4CVCommands::SetPort(const TArray<FString>& Args)
{
	if (Args.Num() == 1)
	{
		int32 PortNum = FCString::Atoi(*Args[0]);
		bool IsSuccessful = FUE4CVServer::Get().NetworkManager->SetPort(PortNum);
		if (IsSuccessful)
		{
			return FExecStatus::OK();
		}
		else
		{
			return FExecStatus::Error(FString::Printf(TEXT("Fail to set port to %d"), PortNum));
		}
	}
	else
	{
		return FExecStatus::InvalidArgument;
	}
}

FExecStatus UE4CVCommands::GetUnrealCVStatus(const TArray<FString>& Args)
{
	FString Msg;
	FUE4CVServer& Server = FUE4CVServer::Get(); // TODO: Can not use a copy constructor, need to disable copy constructor
	if (Server.NetworkManager->IsListening())
	{
		Msg += "Is Listening\n";
	}
	else
	{
		Msg += "Not Listening\n";
	}
	if (Server.NetworkManager->IsConnected())
	{
		Msg += "Client Connected\n";
	}
	else
	{
		Msg += "No Client Connected\n";
	}
	Msg += FString::Printf(TEXT("%d\n"), Server.NetworkManager->PortNum);
	return FExecStatus::OK(Msg);
}
<commit_msg>Update set port command.<commit_after>#include "UnrealCVPrivate.h"
#include "UE4CVCommands.h"
#include "UE4CVServer.h"

void UE4CVCommands::RegisterCommandsPlugin()
{
	FDispatcherDelegate Cmd;
	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::GetPort);
	CommandDispatcher->BindCommand("vget /unrealcv/port", Cmd, "Get port from the plugin listening to");

	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::SetPort);
	CommandDispatcher->BindCommand("vset /unrealcv/port [uint]", Cmd, "Set port the plugin listening to");

	Cmd = FDispatcherDelegate::CreateRaw(this, &UE4CVCommands::GetUnrealCVStatus);
	CommandDispatcher->BindCommand("vget /unrealcv/status", Cmd, "Get camera location");
}

FExecStatus UE4CVCommands::GetPort(const TArray<FString>& Args)
{
	FString Msg = FString::Printf(TEXT("%d"), FUE4CVServer::Get().NetworkManager->PortNum);
	return FExecStatus::OK(Msg);
	// return FExecStatus::InvalidArgument;
}

FExecStatus UE4CVCommands::SetPort(const TArray<FString>& Args)
{
	if (Args.Num() == 1)
	{
		int32 PortNum = FCString::Atoi(*Args[0]);
		bool IsSuccessful = FUE4CVServer::Get().NetworkManager->Start(PortNum);
		if (IsSuccessful)
		{
			return FExecStatus::OK();
		}
		else
		{
			return FExecStatus::Error(FString::Printf(TEXT("Fail to set port to %d"), PortNum));
		}
	}
	else
	{
		return FExecStatus::InvalidArgument;
	}
}

FExecStatus UE4CVCommands::GetUnrealCVStatus(const TArray<FString>& Args)
{
	FString Msg;
	FUE4CVServer& Server = FUE4CVServer::Get(); // TODO: Can not use a copy constructor, need to disable copy constructor
	if (Server.NetworkManager->IsListening())
	{
		Msg += "Is Listening\n";
	}
	else
	{
		Msg += "Not Listening\n";
	}
	if (Server.NetworkManager->IsConnected())
	{
		Msg += "Client Connected\n";
	}
	else
	{
		Msg += "No Client Connected\n";
	}
	Msg += FString::Printf(TEXT("%d\n"), Server.NetworkManager->PortNum);
	return FExecStatus::OK(Msg);
}
<|endoftext|>