<commit_before>/*
    This file is part of Akregator.

    Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "tabwidget.h"

#include <QStyle>
#include <QApplication>
#include <QIcon>
#include <QClipboard>
#include <QHash>
#include <QString>
#include <QToolButton>

#include <QMenu>
#include <QStyleOption>

#include <kapplication.h>
#include <kdebug.h>
#include <ktabwidget.h>
#include <ktabbar.h>
#include <kmenu.h>
#include <krun.h>
#include <klocale.h>
#include <khtmlview.h>
#include <khtml_part.h>
#include <kiconloader.h>
#include <ktoolinvocation.h>
#include <kurl.h>
#include <kmimetype.h>
#include <kio/global.h>

#include "actionmanager.h"
#include "akregatorconfig.h"
#include "frame.h"
#include "framemanager.h"
#include "kernel.h"
#include "openurlrequest.h"
#include "utils/temporaryvalue.h"

#include <cassert>

namespace Akregator {

class TabWidget::Private
{
private:
    TabWidget* const q;

public:
    explicit Private( TabWidget * qq ) : q( qq ), currentMaxLength( 30 ), currentItem( 0 ) {}

    QHash<QWidget*, Frame*> frames;
    QHash<int, Frame*> framesById;
    int currentMaxLength;
    QWidget* currentItem;
    QToolButton* tabsClose;

    QWidget* selectedWidget() const {
        return ( currentItem && q->indexOf(currentItem) != -1 ) ? currentItem : q->currentWidget();
    }

    uint tabBarWidthForMaxChars(int maxLength);
    void setTitle(const QString &title , QWidget* sender);
    void updateTabBarVisibility();
    Frame* currentFrame();
};

void TabWidget::Private::updateTabBarVisibility()
{
    q->setTabBarHidden( ( q->count() <= 1 ) && !Settings::alwaysShowTabBar() );
}

TabWidget::TabWidget(QWidget * parent)
    :KTabWidget(parent), d(new Private( this ) )
{
    setMinimumSize(250,150);
    setTabReorderingEnabled(false);
    connect( this, SIGNAL( currentChanged(int) ),
             this, SLOT( slotTabChanged(int) ) );
    connect(this, SIGNAL(closeRequest(QWidget*)),
            this, SLOT(slotCloseRequest(QWidget*)));
    setCloseButtonEnabled(Settings::closeButtonOnTabs());

    d->tabsClose = new QToolButton(this);
    connect( d->tabsClose, SIGNAL( clicked() ), this,
            SLOT( slotRemoveCurrentFrame() ) );

    d->tabsClose->setIcon( KIcon( "tab-close" ) );
    d->tabsClose->setEnabled( false );
    d->tabsClose->adjustSize();
    d->tabsClose->setToolTip( i18n("Close the current tab"));
    setCornerWidget( d->tabsClose, Qt::TopRightCorner );
    d->updateTabBarVisibility();
}

TabWidget::~TabWidget()
{
    delete d;
}

void TabWidget::slotSettingsChanged()
{
    if (tabsClosable() != Settings::closeButtonOnTabs())
        setTabsClosable(Settings::closeButtonOnTabs());
    d->updateTabBarVisibility();
}

void TabWidget::slotNextTab()
{
    setCurrentIndex((currentIndex()+1) % count());
}

void TabWidget::slotPreviousTab()
{
    if (currentIndex() == 0)
        setCurrentIndex(count()-1);
    else
        setCurrentIndex(currentIndex()-1);
}
void TabWidget::slotSelectFrame(int frameId)
{
    Frame* frame = d->framesById.value(frameId);
    if (frame && frame != d->currentFrame())
    {
        setCurrentWidget(frame);
        if (frame->part() && frame->part()->widget())
        {
            frame->part()->widget()->setFocus();
        }
        else
        {
            frame->setFocus();
        }
    }
}

void TabWidget::slotAddFrame(Frame* frame)
{
    if (!frame)
        return;
    d->frames.insert(frame, frame);
    d->framesById.insert( frame->id(), frame );
    addTab(frame, frame->title());
    connect(frame, SIGNAL(signalTitleChanged(Akregator::Frame*,QString)),
            this, SLOT(slotSetTitle(Akregator::Frame*,QString)));
    connect(frame, SIGNAL(signalIconChanged(Akregator::Frame*,QIcon)),
            this, SLOT(slotSetIcon(Akregator::Frame*,QIcon)));

    if(frame->id() > 0) // MainFrame doesn't emit signalPartDestroyed signals, neither should it
        connect(frame, SIGNAL(signalPartDestroyed(int)), this, SLOT(slotRemoveFrame(int)));
    slotSetTitle(frame, frame->title());
}

Frame * TabWidget::Private::currentFrame()
{
    QWidget* w = q->currentWidget();
    assert( frames.value( w ) );
    return w ? frames.value(w) : 0;
}

void TabWidget::slotFrameZoomIn()
{
    if ( !d->currentFrame() )
        return;
    emit signalZoomInFrame( d->currentFrame()->id() );
}

void TabWidget::slotFrameZoomOut()
{
    if ( !d->currentFrame() )
        return;
    emit signalZoomOutFrame( d->currentFrame()->id() );
}

void TabWidget::slotTabChanged(int index)
{

    Frame* frame = d->frames.value(widget(index));
    d->tabsClose->setEnabled(frame && frame->isRemovable());
    emit signalCurrentFrameChanged(frame ? frame->id() : -1);
}

void TabWidget::tabInserted( int )
{
    d->updateTabBarVisibility();
}

void TabWidget::tabRemoved( int )
{
    d->updateTabBarVisibility();
}

void TabWidget::slotRemoveCurrentFrame()
{
    Frame* const frame = d->currentFrame();
    if (frame)
        emit signalRemoveFrameRequest(frame->id());
}

void TabWidget::slotRemoveFrame(int frameId)
{
    if (!d->framesById.contains(frameId))
        return;
    Frame* f = d->framesById.value(frameId);
    d->frames.remove(f);
    d->framesById.remove(frameId);
    f->disconnect( this );
    removeTab(indexOf(f));
    emit signalRemoveFrameRequest(f->id());
    if (d->currentFrame())
      d->setTitle( d->currentFrame()->title(), currentWidget() );
}

// copied wholesale from KonqFrameTabs
uint TabWidget::Private::tabBarWidthForMaxChars( int maxLength )
{
    int hframe, overlap;
    QStyleOption o;
    hframe = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, &o, q );
    overlap = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabOverlap, &o, q );

    QFontMetrics fm = q->tabBar()->fontMetrics();
    int x = 0;
    for (int i = 0; i < q->count(); ++i)
    {
        Frame* f = frames.value(q->widget(i));
        if (!f) {
            continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
        }
        QString newTitle = f->title();
        if ( newTitle.length() > maxLength )
            newTitle = newTitle.left( maxLength-3 ) + "...";

        int lw = fm.width( newTitle );
        int iw = q->tabBar()->tabIcon( i ).pixmap( q->tabBar()->style()->pixelMetric(
QStyle::PM_SmallIconSize ), QIcon::Normal
).width() + 4;

        x += ( q->tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, &o,
               QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), q ) ).width();
    }
    return x;
}

void TabWidget::slotSetTitle(Frame* frame, const QString& title)
{
    d->setTitle(title, frame);
}

void TabWidget::slotSetIcon(Akregator::Frame* frame, const QIcon& icon)
{
    const int idx = indexOf( frame );
    if ( idx < 0 )
        return;
    setTabIcon( idx, icon );
}

void TabWidget::Private::setTitle( const QString &title, QWidget* sender)
{
    int senderIndex = q->indexOf(sender);

    q->setTabToolTip( senderIndex, QString() );

    uint lcw=0, rcw=0;
    int tabBarHeight = q->tabBar()->sizeHint().height();

    QWidget* leftCorner = q->cornerWidget( Qt::TopLeftCorner );

    if ( leftCorner  && leftCorner->isVisible() )
        lcw = qMax( leftCorner->width(), tabBarHeight );

    QWidget* rightCorner = q->cornerWidget( Qt::TopRightCorner );

    if ( rightCorner && rightCorner->isVisible() )
        rcw = qMax( rightCorner->width(), tabBarHeight );
    uint maxTabBarWidth = q->width() - lcw - rcw;

    int newMaxLength = 30;

    for ( ; newMaxLength > 3; newMaxLength-- )
    {
        if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
            break;
    }

    QString newTitle = title;
    if ( newTitle.length() > newMaxLength )
    {
        q->setTabToolTip( senderIndex, newTitle );
        newTitle = newTitle.left( newMaxLength-3 ) + "...";
    }

    newTitle.replace( '&', "&&" );

    if ( q->tabText(senderIndex) != newTitle )
        q->setTabText( senderIndex, newTitle );

    if( newMaxLength != currentMaxLength )
    {
        for( int i = 0; i < q->count(); ++i)
        {
            Frame* f = frames.value(q->widget(i));
            if ( !f ) {
                continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
            }
            newTitle = f->title();
            int index = q->indexOf(q->widget( i ));
            q->setTabToolTip( index, QString() );

            if ( newTitle.length() > newMaxLength )
            {
                q->setTabToolTip( index, newTitle );
                newTitle = newTitle.left( newMaxLength-3 ) + "...";
            }

            newTitle.replace( '&', "&&" );
            if ( newTitle != q->tabText( index ) )
                q->setTabText( index, newTitle );
        }
        currentMaxLength = newMaxLength;
    }
}

void TabWidget::contextMenu(int i, const QPoint &p)
{
    QWidget* w = ActionManager::getInstance()->container("tab_popup");
    TemporaryValue<QWidget*> tmp( d->currentItem, widget( i ) );
    //kDebug() << indexOf(d->currentItem);
    // FIXME: do not hardcode index of maintab
    if (w && indexOf(d->currentItem) != 0)
        static_cast<QMenu *>(w)->exec(p);
}

void TabWidget::slotDetachTab()
{
    Frame* frame = d->frames.value( d->selectedWidget() );

    if (frame && frame->url().isValid() && frame->isRemovable())
    {
        OpenUrlRequest request;
        request.setUrl(frame->url());
        request.setOptions(OpenUrlRequest::ExternalBrowser);
        emit signalOpenUrlRequest(request);
        slotCloseTab();
    }
}

void TabWidget::slotCopyLinkAddress()
{
    Frame* frame = d->frames.value( d->selectedWidget() );

    if (frame && frame->url().isValid())
    {
        KUrl url = frame->url();
        // don't set url to selection as it's a no-no according to a fd.o spec
        //kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Selection);
        kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Clipboard);
    }
}

void TabWidget::slotCloseTab()
{
    QWidget* widget =  d->selectedWidget();
    Frame* frame = d->frames.value( widget );

    if (frame == 0 || !frame->isRemovable() )
        return;

    emit signalRemoveFrameRequest(frame->id());
}

void TabWidget::initiateDrag(int tab)
{
    Frame* frame = d->frames.value(widget(tab));

    if (frame && frame->url().isValid())
    {
        KUrl::List lst;
        lst.append( frame->url() );
        QDrag* drag = new QDrag( this );
        QMimeData *md = new QMimeData;
        drag->setMimeData( md );
        lst.populateMimeData( md );
        drag->setPixmap( KIO::pixmapForUrl( lst.first(), 0, KIconLoader::Small ) );
        drag->start();
    }
}

void TabWidget::slotCloseRequest(QWidget* widget)
{
    if (d->frames.value(widget))
        emit signalRemoveFrameRequest(d->frames.value(widget)->id());
}

} // namespace Akregator

#include "tabwidget.moc"
<commit_msg>changed deprecated function call<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "tabwidget.h"

#include <QStyle>
#include <QApplication>
#include <QIcon>
#include <QClipboard>
#include <QHash>
#include <QString>
#include <QToolButton>

#include <QMenu>
#include <QStyleOption>

#include <kapplication.h>
#include <kdebug.h>
#include <ktabwidget.h>
#include <ktabbar.h>
#include <kmenu.h>
#include <krun.h>
#include <klocale.h>
#include <khtmlview.h>
#include <khtml_part.h>
#include <kiconloader.h>
#include <ktoolinvocation.h>
#include <kurl.h>
#include <kmimetype.h>
#include <kio/global.h>

#include "actionmanager.h"
#include "akregatorconfig.h"
#include "frame.h"
#include "framemanager.h"
#include "kernel.h"
#include "openurlrequest.h"
#include "utils/temporaryvalue.h"

#include <cassert>

namespace Akregator {

class TabWidget::Private
{
private:
    TabWidget* const q;

public:
    explicit Private( TabWidget * qq ) : q( qq ), currentMaxLength( 30 ), currentItem( 0 ) {}

    QHash<QWidget*, Frame*> frames;
    QHash<int, Frame*> framesById;
    int currentMaxLength;
    QWidget* currentItem;
    QToolButton* tabsClose;

    QWidget* selectedWidget() const {
        return ( currentItem && q->indexOf(currentItem) != -1 ) ? currentItem : q->currentWidget();
    }

    uint tabBarWidthForMaxChars(int maxLength);
    void setTitle(const QString &title , QWidget* sender);
    void updateTabBarVisibility();
    Frame* currentFrame();
};

void TabWidget::Private::updateTabBarVisibility()
{
    q->setTabBarHidden( ( q->count() <= 1 ) && !Settings::alwaysShowTabBar() );
}

TabWidget::TabWidget(QWidget * parent)
    :KTabWidget(parent), d(new Private( this ) )
{
    setMinimumSize(250,150);
    setTabReorderingEnabled(false);
    connect( this, SIGNAL( currentChanged(int) ),
             this, SLOT( slotTabChanged(int) ) );
    connect(this, SIGNAL(closeRequest(QWidget*)),
            this, SLOT(slotCloseRequest(QWidget*)));
    setTabsClosable(Settings::closeButtonOnTabs());

    d->tabsClose = new QToolButton(this);
    connect( d->tabsClose, SIGNAL( clicked() ), this,
            SLOT( slotRemoveCurrentFrame() ) );

    d->tabsClose->setIcon( KIcon( "tab-close" ) );
    d->tabsClose->setEnabled( false );
    d->tabsClose->adjustSize();
    d->tabsClose->setToolTip( i18n("Close the current tab"));
    setCornerWidget( d->tabsClose, Qt::TopRightCorner );
    d->updateTabBarVisibility();
}

TabWidget::~TabWidget()
{
    delete d;
}

void TabWidget::slotSettingsChanged()
{
    if (tabsClosable() != Settings::closeButtonOnTabs())
        setTabsClosable(Settings::closeButtonOnTabs());
    d->updateTabBarVisibility();
}

void TabWidget::slotNextTab()
{
    setCurrentIndex((currentIndex()+1) % count());
}

void TabWidget::slotPreviousTab()
{
    if (currentIndex() == 0)
        setCurrentIndex(count()-1);
    else
        setCurrentIndex(currentIndex()-1);
}
void TabWidget::slotSelectFrame(int frameId)
{
    Frame* frame = d->framesById.value(frameId);
    if (frame && frame != d->currentFrame())
    {
        setCurrentWidget(frame);
        if (frame->part() && frame->part()->widget())
        {
            frame->part()->widget()->setFocus();
        }
        else
        {
            frame->setFocus();
        }
    }
}

void TabWidget::slotAddFrame(Frame* frame)
{
    if (!frame)
        return;
    d->frames.insert(frame, frame);
    d->framesById.insert( frame->id(), frame );
    addTab(frame, frame->title());
    connect(frame, SIGNAL(signalTitleChanged(Akregator::Frame*,QString)),
            this, SLOT(slotSetTitle(Akregator::Frame*,QString)));
    connect(frame, SIGNAL(signalIconChanged(Akregator::Frame*,QIcon)),
            this, SLOT(slotSetIcon(Akregator::Frame*,QIcon)));

    if(frame->id() > 0) // MainFrame doesn't emit signalPartDestroyed signals, neither should it
        connect(frame, SIGNAL(signalPartDestroyed(int)), this, SLOT(slotRemoveFrame(int)));
    slotSetTitle(frame, frame->title());
}

Frame * TabWidget::Private::currentFrame()
{
    QWidget* w = q->currentWidget();
    assert( frames.value( w ) );
    return w ? frames.value(w) : 0;
}

void TabWidget::slotFrameZoomIn()
{
    if ( !d->currentFrame() )
        return;
    emit signalZoomInFrame( d->currentFrame()->id() );
}

void TabWidget::slotFrameZoomOut()
{
    if ( !d->currentFrame() )
        return;
    emit signalZoomOutFrame( d->currentFrame()->id() );
}

void TabWidget::slotTabChanged(int index)
{

    Frame* frame = d->frames.value(widget(index));
    d->tabsClose->setEnabled(frame && frame->isRemovable());
    emit signalCurrentFrameChanged(frame ? frame->id() : -1);
}

void TabWidget::tabInserted( int )
{
    d->updateTabBarVisibility();
}

void TabWidget::tabRemoved( int )
{
    d->updateTabBarVisibility();
}

void TabWidget::slotRemoveCurrentFrame()
{
    Frame* const frame = d->currentFrame();
    if (frame)
        emit signalRemoveFrameRequest(frame->id());
}

void TabWidget::slotRemoveFrame(int frameId)
{
    if (!d->framesById.contains(frameId))
        return;
    Frame* f = d->framesById.value(frameId);
    d->frames.remove(f);
    d->framesById.remove(frameId);
    f->disconnect( this );
    removeTab(indexOf(f));
    emit signalRemoveFrameRequest(f->id());
    if (d->currentFrame())
      d->setTitle( d->currentFrame()->title(), currentWidget() );
}

// copied wholesale from KonqFrameTabs
uint TabWidget::Private::tabBarWidthForMaxChars( int maxLength )
{
    int hframe, overlap;
    QStyleOption o;
    hframe = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, &o, q );
    overlap = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabOverlap, &o, q );

    QFontMetrics fm = q->tabBar()->fontMetrics();
    int x = 0;
    for (int i = 0; i < q->count(); ++i)
    {
        Frame* f = frames.value(q->widget(i));
        if (!f) {
            continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
        }
        QString newTitle = f->title();
        if ( newTitle.length() > maxLength )
            newTitle = newTitle.left( maxLength-3 ) + "...";

        int lw = fm.width( newTitle );
        int iw = q->tabBar()->tabIcon( i ).pixmap( q->tabBar()->style()->pixelMetric(
QStyle::PM_SmallIconSize ), QIcon::Normal
).width() + 4;

        x += ( q->tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, &o,
               QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), q ) ).width();
    }
    return x;
}

void TabWidget::slotSetTitle(Frame* frame, const QString& title)
{
    d->setTitle(title, frame);
}

void TabWidget::slotSetIcon(Akregator::Frame* frame, const QIcon& icon)
{
    const int idx = indexOf( frame );
    if ( idx < 0 )
        return;
    setTabIcon( idx, icon );
}

void TabWidget::Private::setTitle( const QString &title, QWidget* sender)
{
    int senderIndex = q->indexOf(sender);

    q->setTabToolTip( senderIndex, QString() );

    uint lcw=0, rcw=0;
    int tabBarHeight = q->tabBar()->sizeHint().height();

    QWidget* leftCorner = q->cornerWidget( Qt::TopLeftCorner );

    if ( leftCorner  && leftCorner->isVisible() )
        lcw = qMax( leftCorner->width(), tabBarHeight );

    QWidget* rightCorner = q->cornerWidget( Qt::TopRightCorner );

    if ( rightCorner && rightCorner->isVisible() )
        rcw = qMax( rightCorner->width(), tabBarHeight );
    uint maxTabBarWidth = q->width() - lcw - rcw;

    int newMaxLength = 30;

    for ( ; newMaxLength > 3; newMaxLength-- )
    {
        if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
            break;
    }

    QString newTitle = title;
    if ( newTitle.length() > newMaxLength )
    {
        q->setTabToolTip( senderIndex, newTitle );
        newTitle = newTitle.left( newMaxLength-3 ) + "...";
    }

    newTitle.replace( '&', "&&" );

    if ( q->tabText(senderIndex) != newTitle )
        q->setTabText( senderIndex, newTitle );

    if( newMaxLength != currentMaxLength )
    {
        for( int i = 0; i < q->count(); ++i)
        {
            Frame* f = frames.value(q->widget(i));
            if ( !f ) {
                continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
            }
            newTitle = f->title();
            int index = q->indexOf(q->widget( i ));
            q->setTabToolTip( index, QString() );

            if ( newTitle.length() > newMaxLength )
            {
                q->setTabToolTip( index, newTitle );
                newTitle = newTitle.left( newMaxLength-3 ) + "...";
            }

            newTitle.replace( '&', "&&" );
            if ( newTitle != q->tabText( index ) )
                q->setTabText( index, newTitle );
        }
        currentMaxLength = newMaxLength;
    }
}

void TabWidget::contextMenu(int i, const QPoint &p)
{
    QWidget* w = ActionManager::getInstance()->container("tab_popup");
    TemporaryValue<QWidget*> tmp( d->currentItem, widget( i ) );
    //kDebug() << indexOf(d->currentItem);
    // FIXME: do not hardcode index of maintab
    if (w && indexOf(d->currentItem) != 0)
        static_cast<QMenu *>(w)->exec(p);
}

void TabWidget::slotDetachTab()
{
    Frame* frame = d->frames.value( d->selectedWidget() );

    if (frame && frame->url().isValid() && frame->isRemovable())
    {
        OpenUrlRequest request;
        request.setUrl(frame->url());
        request.setOptions(OpenUrlRequest::ExternalBrowser);
        emit signalOpenUrlRequest(request);
        slotCloseTab();
    }
}

void TabWidget::slotCopyLinkAddress()
{
    Frame* frame = d->frames.value( d->selectedWidget() );

    if (frame && frame->url().isValid())
    {
        KUrl url = frame->url();
        // don't set url to selection as it's a no-no according to a fd.o spec
        //kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Selection);
        kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Clipboard);
    }
}

void TabWidget::slotCloseTab()
{
    QWidget* widget =  d->selectedWidget();
    Frame* frame = d->frames.value( widget );

    if (frame == 0 || !frame->isRemovable() )
        return;

    emit signalRemoveFrameRequest(frame->id());
}

void TabWidget::initiateDrag(int tab)
{
    Frame* frame = d->frames.value(widget(tab));

    if (frame && frame->url().isValid())
    {
        KUrl::List lst;
        lst.append( frame->url() );
        QDrag* drag = new QDrag( this );
        QMimeData *md = new QMimeData;
        drag->setMimeData( md );
        lst.populateMimeData( md );
        drag->setPixmap( KIO::pixmapForUrl( lst.first(), 0, KIconLoader::Small ) );
        drag->start();
    }
}

void TabWidget::slotCloseRequest(QWidget* widget)
{
    if (d->frames.value(widget))
        emit signalRemoveFrameRequest(d->frames.value(widget)->id());
}

} // namespace Akregator

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


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

#include "tensorflow/core/kernels/data/dataset_test_base.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/test.h"

namespace tensorflow {
namespace data {
namespace experimental {
namespace {

constexpr char kNodeName[] = "lmdb_dataset";
constexpr char kIteratorPrefix[] = "Iterator";
constexpr char kDataFileName[] = "data.mdb";
constexpr char kDataFileLoc[] = "core/lib/lmdb/testdata";

class LMDBDatasetParams : public DatasetParams {
 public:
  LMDBDatasetParams(std::vector<std::string> filenames,
                    DataTypeVector output_dtypes,
                    std::vector<PartialTensorShape> output_shapes,
                    string node_name)
      : DatasetParams(std::move(output_dtypes), std::move(output_shapes),
                      std::move(kNodeName)),
        filenames_(CreateTensor<std::string>(
            TensorShape({static_cast<int>(filenames.size())}), filenames)) {}

  virtual std::vector<Tensor> GetInputTensors() const override {
    return {filenames_};
  }

  virtual Status GetInputNames(
      std::vector<string>* input_names) const override {
    *input_names = {LMDBDatasetOp::kFileNames};
    return Status::OK();
  }

  virtual Status GetAttributes(AttributeVector* attributes) const override {
    *attributes = {{LMDBDatasetOp::kOutputTypes, output_dtypes_},
                   {LMDBDatasetOp::kOutputShapes, output_shapes_}};
    return Status::OK();
  }

  virtual string dataset_type() const override {
    return LMDBDatasetOp::kDatasetType;
  }

 private:
  // Names of binary database files to read, boxed up inside a Tensor of
  // strings
  Tensor filenames_;
};

class LMDBDatasetOpTest : public DatasetOpsTestBaseV2 {};

// Copy our test data file to the current test program's temporary
// directory, and return the full path to the copied file.
// This copying is necessary because LMDB creates lock files adjacent
// to files that it reads.
string MaybeCopyDataFile() {
  string src_loc =
      io::JoinPath(testing::TensorFlowSrcRoot(), kDataFileLoc, kDataFileName);
  string dest_loc = io::JoinPath(testing::TmpDir(), kDataFileName);

  FileSystem* fs;  // Pointer to singleton
  TF_EXPECT_OK(Env::Default()->GetFileSystemForFile(src_loc, &fs));

  // FileSystem::FileExists currently returns Status::OK() if the file
  // exists and errors::NotFound() if the file doesn't exist. There's no
  // indication in the code or docs about whether other error codes may be
  // added in the future, so we code defensively here.
  Status exists_status = fs->FileExists(dest_loc);
  if (exists_status.code() == error::NOT_FOUND) {
    TF_EXPECT_OK(fs->CopyFile(src_loc, dest_loc));
  } else {
    TF_EXPECT_OK(exists_status);
  }

  return dest_loc;
}

LMDBDatasetParams SingleValidInput() {
  return {/*filenames=*/{MaybeCopyDataFile()},
          /*output_dtypes=*/{DT_STRING, DT_STRING},
          /*output_shapes=*/{PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams TwoValidInputs() {
  return {/*filenames*/ {MaybeCopyDataFile(), MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams EmptyInput() {
  return {/*filenames*/ {},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams InvalidPathAtStart() {
  return {/*filenames*/ {"This is not a valid filename", MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams InvalidPathInMiddle() {
  return {/*filenames*/ {MaybeCopyDataFile(), "This is not a valid filename",
                         MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

// The tensors we expect to see each time we read through the input data file.
const std::vector<Tensor> kFileOutput = CreateTensors<string>(
    TensorShape({}),
    {
        // Each call to GetNext() produces two scalar string tensors, but the
        // test harness expects to receive a flat vector
        {"0"}, {"a"},  //
        {"1"}, {"b"},  //
        {"2"}, {"c"},  //
        {"3"}, {"d"},  //
        {"4"}, {"e"},  //
        {"5"}, {"f"},  //
        {"6"}, {"g"},  //
        {"7"}, {"h"},  //
        {"8"}, {"i"},  //
        {"9"}, {"j"},  //
    });

std::vector<GetNextTestCase<LMDBDatasetParams>> GetNextTestCases() {
  // STL vectors don't have a "concatenate two vectors into a new vector"
  // operation, so...
  std::vector<Tensor> output_twice;
  output_twice.insert(output_twice.end(), kFileOutput.cbegin(),
                      kFileOutput.cend());
  output_twice.insert(output_twice.end(), kFileOutput.cbegin(),
                      kFileOutput.cend());

  return {
      {/*dataset_params=*/SingleValidInput(), /*expected_outputs=*/kFileOutput},
      {/*dataset_params=*/TwoValidInputs(), /*expected_outputs=*/output_twice},
      {/*dataset_params=*/EmptyInput(), /*expected_outputs=*/{}}};
}

ITERATOR_GET_NEXT_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                         GetNextTestCases());

TEST_F(LMDBDatasetOpTest, InvalidPathAtStart) {
  auto dataset_params = InvalidPathAtStart();
  TF_ASSERT_OK(Initialize(dataset_params));

  // Errors about invalid files are only raised when attempting to read data.
  bool end_of_sequence = false;
  std::vector<Tensor> out_tensors;
  std::vector<Tensor> next;

  Status get_next_status =
      iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence);

  EXPECT_EQ(get_next_status.code(), error::INVALID_ARGUMENT);
}

TEST_F(LMDBDatasetOpTest, InvalidPathInMiddle) {
  auto dataset_params = InvalidPathInMiddle();
  TF_ASSERT_OK(Initialize(dataset_params));

  bool end_of_sequence = false;
  std::vector<Tensor> out_tensors;
  std::vector<Tensor> next;

  // First 10 rows should be ok
  for (int i = 0; i < 10; ++i) {
    TF_ASSERT_OK(
        iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence));
    EXPECT_FALSE(end_of_sequence);
  }

  // Next read operation should raise an error
  Status get_next_status =
      iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence);
  EXPECT_EQ(get_next_status.code(), error::INVALID_ARGUMENT);
}

std::vector<DatasetNodeNameTestCase<LMDBDatasetParams>>
DatasetNodeNameTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_node_name=*/kNodeName}};
}

DATASET_NODE_NAME_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                         DatasetNodeNameTestCases());

std::vector<DatasetTypeStringTestCase<LMDBDatasetParams>>
DatasetTypeStringTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_dataset_type_string=*/name_utils::OpName(
               LMDBDatasetOp::kDatasetType)}};
}

DATASET_TYPE_STRING_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                           DatasetTypeStringTestCases());

std::vector<DatasetOutputDtypesTestCase<LMDBDatasetParams>>
DatasetOutputDtypesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_dtypes=*/{DT_STRING, DT_STRING}}};
}

DATASET_OUTPUT_DTYPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                             DatasetOutputDtypesTestCases());

std::vector<DatasetOutputShapesTestCase<LMDBDatasetParams>>
DatasetOutputShapesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_shapes=*/{PartialTensorShape({}),
                                       PartialTensorShape({})}}};
}

DATASET_OUTPUT_SHAPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                             DatasetOutputShapesTestCases());

std::vector<CardinalityTestCase<LMDBDatasetParams>> CardinalityTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_cardinality=*/kUnknownCardinality}};
}

DATASET_CARDINALITY_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                           CardinalityTestCases());

std::vector<IteratorOutputDtypesTestCase<LMDBDatasetParams>>
IteratorOutputDtypesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_dtypes=*/{DT_STRING, DT_STRING}}};
}

ITERATOR_OUTPUT_DTYPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                              IteratorOutputDtypesTestCases());

std::vector<IteratorOutputShapesTestCase<LMDBDatasetParams>>
IteratorOutputShapesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_shapes=*/{PartialTensorShape({}),
                                       PartialTensorShape({})}}};
}

ITERATOR_OUTPUT_SHAPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                              IteratorOutputShapesTestCases());

std::vector<IteratorPrefixTestCase<LMDBDatasetParams>>
IteratorOutputPrefixTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_iterator_prefix=*/name_utils::IteratorPrefix(
               LMDBDatasetOp::kDatasetType, kIteratorPrefix)}};
}

ITERATOR_PREFIX_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                       IteratorOutputPrefixTestCases());

// No test of save and restore; save/restore functionality is not implemented
// for this dataset.

}  // namespace
}  // namespace experimental
}  // namespace data
}  // namespace tensorflow
<commit_msg>DatasetOpsTestBaseV2 => DatasetOpsTestBase<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/kernels/data/experimental/lmdb_dataset_op.h"

#include "tensorflow/core/kernels/data/dataset_test_base.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/test.h"

namespace tensorflow {
namespace data {
namespace experimental {
namespace {

constexpr char kNodeName[] = "lmdb_dataset";
constexpr char kIteratorPrefix[] = "Iterator";
constexpr char kDataFileName[] = "data.mdb";
constexpr char kDataFileLoc[] = "core/lib/lmdb/testdata";

class LMDBDatasetParams : public DatasetParams {
 public:
  LMDBDatasetParams(std::vector<std::string> filenames,
                    DataTypeVector output_dtypes,
                    std::vector<PartialTensorShape> output_shapes,
                    string node_name)
      : DatasetParams(std::move(output_dtypes), std::move(output_shapes),
                      std::move(kNodeName)),
        filenames_(CreateTensor<std::string>(
            TensorShape({static_cast<int>(filenames.size())}), filenames)) {}

  virtual std::vector<Tensor> GetInputTensors() const override {
    return {filenames_};
  }

  virtual Status GetInputNames(
      std::vector<string>* input_names) const override {
    *input_names = {LMDBDatasetOp::kFileNames};
    return Status::OK();
  }

  virtual Status GetAttributes(AttributeVector* attributes) const override {
    *attributes = {{LMDBDatasetOp::kOutputTypes, output_dtypes_},
                   {LMDBDatasetOp::kOutputShapes, output_shapes_}};
    return Status::OK();
  }

  virtual string dataset_type() const override {
    return LMDBDatasetOp::kDatasetType;
  }

 private:
  // Names of binary database files to read, boxed up inside a Tensor of
  // strings
  Tensor filenames_;
};

class LMDBDatasetOpTest : public DatasetOpsTestBase {};

// Copy our test data file to the current test program's temporary
// directory, and return the full path to the copied file.
// This copying is necessary because LMDB creates lock files adjacent
// to files that it reads.
string MaybeCopyDataFile() {
  string src_loc =
      io::JoinPath(testing::TensorFlowSrcRoot(), kDataFileLoc, kDataFileName);
  string dest_loc = io::JoinPath(testing::TmpDir(), kDataFileName);

  FileSystem* fs;  // Pointer to singleton
  TF_EXPECT_OK(Env::Default()->GetFileSystemForFile(src_loc, &fs));

  // FileSystem::FileExists currently returns Status::OK() if the file
  // exists and errors::NotFound() if the file doesn't exist. There's no
  // indication in the code or docs about whether other error codes may be
  // added in the future, so we code defensively here.
  Status exists_status = fs->FileExists(dest_loc);
  if (exists_status.code() == error::NOT_FOUND) {
    TF_EXPECT_OK(fs->CopyFile(src_loc, dest_loc));
  } else {
    TF_EXPECT_OK(exists_status);
  }

  return dest_loc;
}

LMDBDatasetParams SingleValidInput() {
  return {/*filenames=*/{MaybeCopyDataFile()},
          /*output_dtypes=*/{DT_STRING, DT_STRING},
          /*output_shapes=*/{PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams TwoValidInputs() {
  return {/*filenames*/ {MaybeCopyDataFile(), MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams EmptyInput() {
  return {/*filenames*/ {},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams InvalidPathAtStart() {
  return {/*filenames*/ {"This is not a valid filename", MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

LMDBDatasetParams InvalidPathInMiddle() {
  return {/*filenames*/ {MaybeCopyDataFile(), "This is not a valid filename",
                         MaybeCopyDataFile()},
          /*output_dtypes*/ {DT_STRING, DT_STRING},
          /*output_shapes*/ {PartialTensorShape({}), PartialTensorShape({})},
          /*node_name=*/kNodeName};
}

// The tensors we expect to see each time we read through the input data file.
const std::vector<Tensor> kFileOutput = CreateTensors<string>(
    TensorShape({}),
    {
        // Each call to GetNext() produces two scalar string tensors, but the
        // test harness expects to receive a flat vector
        {"0"}, {"a"},  //
        {"1"}, {"b"},  //
        {"2"}, {"c"},  //
        {"3"}, {"d"},  //
        {"4"}, {"e"},  //
        {"5"}, {"f"},  //
        {"6"}, {"g"},  //
        {"7"}, {"h"},  //
        {"8"}, {"i"},  //
        {"9"}, {"j"},  //
    });

std::vector<GetNextTestCase<LMDBDatasetParams>> GetNextTestCases() {
  // STL vectors don't have a "concatenate two vectors into a new vector"
  // operation, so...
  std::vector<Tensor> output_twice;
  output_twice.insert(output_twice.end(), kFileOutput.cbegin(),
                      kFileOutput.cend());
  output_twice.insert(output_twice.end(), kFileOutput.cbegin(),
                      kFileOutput.cend());

  return {
      {/*dataset_params=*/SingleValidInput(), /*expected_outputs=*/kFileOutput},
      {/*dataset_params=*/TwoValidInputs(), /*expected_outputs=*/output_twice},
      {/*dataset_params=*/EmptyInput(), /*expected_outputs=*/{}}};
}

ITERATOR_GET_NEXT_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                         GetNextTestCases());

TEST_F(LMDBDatasetOpTest, InvalidPathAtStart) {
  auto dataset_params = InvalidPathAtStart();
  TF_ASSERT_OK(Initialize(dataset_params));

  // Errors about invalid files are only raised when attempting to read data.
  bool end_of_sequence = false;
  std::vector<Tensor> out_tensors;
  std::vector<Tensor> next;

  Status get_next_status =
      iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence);

  EXPECT_EQ(get_next_status.code(), error::INVALID_ARGUMENT);
}

TEST_F(LMDBDatasetOpTest, InvalidPathInMiddle) {
  auto dataset_params = InvalidPathInMiddle();
  TF_ASSERT_OK(Initialize(dataset_params));

  bool end_of_sequence = false;
  std::vector<Tensor> out_tensors;
  std::vector<Tensor> next;

  // First 10 rows should be ok
  for (int i = 0; i < 10; ++i) {
    TF_ASSERT_OK(
        iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence));
    EXPECT_FALSE(end_of_sequence);
  }

  // Next read operation should raise an error
  Status get_next_status =
      iterator_->GetNext(iterator_ctx_.get(), &next, &end_of_sequence);
  EXPECT_EQ(get_next_status.code(), error::INVALID_ARGUMENT);
}

std::vector<DatasetNodeNameTestCase<LMDBDatasetParams>>
DatasetNodeNameTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_node_name=*/kNodeName}};
}

DATASET_NODE_NAME_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                         DatasetNodeNameTestCases());

std::vector<DatasetTypeStringTestCase<LMDBDatasetParams>>
DatasetTypeStringTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_dataset_type_string=*/name_utils::OpName(
               LMDBDatasetOp::kDatasetType)}};
}

DATASET_TYPE_STRING_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                           DatasetTypeStringTestCases());

std::vector<DatasetOutputDtypesTestCase<LMDBDatasetParams>>
DatasetOutputDtypesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_dtypes=*/{DT_STRING, DT_STRING}}};
}

DATASET_OUTPUT_DTYPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                             DatasetOutputDtypesTestCases());

std::vector<DatasetOutputShapesTestCase<LMDBDatasetParams>>
DatasetOutputShapesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_shapes=*/{PartialTensorShape({}),
                                       PartialTensorShape({})}}};
}

DATASET_OUTPUT_SHAPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                             DatasetOutputShapesTestCases());

std::vector<CardinalityTestCase<LMDBDatasetParams>> CardinalityTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_cardinality=*/kUnknownCardinality}};
}

DATASET_CARDINALITY_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                           CardinalityTestCases());

std::vector<IteratorOutputDtypesTestCase<LMDBDatasetParams>>
IteratorOutputDtypesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_dtypes=*/{DT_STRING, DT_STRING}}};
}

ITERATOR_OUTPUT_DTYPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                              IteratorOutputDtypesTestCases());

std::vector<IteratorOutputShapesTestCase<LMDBDatasetParams>>
IteratorOutputShapesTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_output_shapes=*/{PartialTensorShape({}),
                                       PartialTensorShape({})}}};
}

ITERATOR_OUTPUT_SHAPES_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                              IteratorOutputShapesTestCases());

std::vector<IteratorPrefixTestCase<LMDBDatasetParams>>
IteratorOutputPrefixTestCases() {
  return {{/*dataset_params=*/SingleValidInput(),
           /*expected_iterator_prefix=*/name_utils::IteratorPrefix(
               LMDBDatasetOp::kDatasetType, kIteratorPrefix)}};
}

ITERATOR_PREFIX_TEST_P(LMDBDatasetOpTest, LMDBDatasetParams,
                       IteratorOutputPrefixTestCases());

// No test of save and restore; save/restore functionality is not implemented
// for this dataset.

}  // namespace
}  // namespace experimental
}  // namespace data
}  // namespace tensorflow
<|endoftext|>


<commit_before>#include "../headers/geom.h"
#include <typeinfo>
#include "../headers/geosAlgorithm.h"

namespace geos {

Polygon::Polygon(){
	shell=new LinearRing();
	holes=new vector<Geometry *>();
}
Polygon::Polygon(const Polygon &p): Geometry(p.precisionModel, p.SRID){
	shell=new LinearRing(*p.shell);
	holes=new vector<Geometry *>();
	for(int i=0;i<(int)p.holes->size();i++) {
		LinearRing *h=new LinearRing(* (LinearRing*)(*p.holes)[i]);
		holes->push_back(h);
	}
}

Polygon::Polygon(LinearRing *newShell, PrecisionModel* precisionModel, int SRID): Geometry(precisionModel, SRID) {
	if (newShell==NULL)
		newShell=new LinearRing(CoordinateListFactory::internalFactory->createCoordinateList(), precisionModel, SRID);
	holes=new vector<Geometry *>();
	if (hasNullElements(holes)) {
		delete newShell;
		delete holes;
		throw new IllegalArgumentException("holes must not contain null elements");
	}
	if (newShell->isEmpty() && hasNonEmptyElements(holes)) {
		delete newShell;
		delete holes;
		throw new IllegalArgumentException("shell is empty but holes are not");
	}
	shell=newShell;
}

Polygon::Polygon(LinearRing *newShell, vector<Geometry *> *newHoles,
				 PrecisionModel* precisionModel, int SRID):
				Geometry(precisionModel, SRID) {
	if (newShell==NULL)
		newShell=new LinearRing(CoordinateListFactory::internalFactory->createCoordinateList(), precisionModel, SRID);

	if (newHoles==NULL)
		newHoles=new vector<Geometry *>();

	if (hasNullElements(newHoles)) {
		delete newShell;
		delete newHoles;
		throw new IllegalArgumentException("holes must not contain null elements");
	}
	if (newShell->isEmpty() && hasNonEmptyElements(newHoles)) {
		delete newShell;
		delete newHoles;
		throw new IllegalArgumentException("shell is empty but holes are not");
	}
	shell=newShell;
	holes=newHoles;
}

CoordinateList* Polygon::getCoordinates() const {
	if (isEmpty()) {
		return CoordinateListFactory::internalFactory->createCoordinateList();
	}
	CoordinateList *coordinates=CoordinateListFactory::internalFactory->createCoordinateList(getNumPoints());
	int k = -1;
	CoordinateList* shellCoordinates=shell->getCoordinates();
	for (int x = 0; x < shellCoordinates->getSize(); x++) {
		k++;
		coordinates->setAt(shellCoordinates->getAt(x),k);
	}
	delete shellCoordinates;
	for (unsigned int i = 0; i < holes->size(); i++) {
		CoordinateList* childCoordinates=((LinearRing *)(*holes)[i])->getCoordinates();
		for (int j = 0; j < childCoordinates->getSize(); j++) {
			k++;
			coordinates->setAt(childCoordinates->getAt(j),k);
		}
		delete childCoordinates;
	}
	return coordinates;
}

int Polygon::getNumPoints() const {
	int numPoints = shell->getNumPoints();
	for (unsigned int i = 0; i < holes->size(); i++) {
		numPoints += ((LinearRing *)(*holes)[i])->getNumPoints();
	}
	return numPoints;
}

int Polygon::getDimension() const {
	return 2;
}

int Polygon::getBoundaryDimension() const {
	return 1;
}

bool Polygon::isEmpty() const {
	return shell->isEmpty();
}

bool Polygon::isSimple() const {
	return true;
}

const LineString* Polygon::getExteriorRing() const {
	return shell;
}

int Polygon::getNumInteriorRing() const {
	return (int)holes->size();
}

const LineString* Polygon::getInteriorRingN(int n) const {
	return (LineString *) (*holes)[n];
}

string Polygon::getGeometryType() const {
	return "Polygon";
}

Geometry* Polygon::getBoundary() const {
	if (isEmpty()) {
		return new GeometryCollection(NULL, precisionModel, SRID);
	}
	vector<Geometry *> *rings=new vector<Geometry *>(holes->size() + 1);
	(*rings)[0]=new LineString(*shell);
	for (unsigned int i=0; i<holes->size(); i++) {
		(*rings)[i + 1] =new LineString(*(LineString*)(*holes)[i]);
	}
	return new MultiLineString(rings, precisionModel, SRID);
}

Envelope* Polygon::computeEnvelopeInternal() const {
	return shell->getEnvelopeInternal();
}

bool Polygon::equalsExact(const Geometry *other, double tolerance) const {
	if (!isEquivalentClass(other)) {
		return false;
	}
	const Polygon* otherPolygon=dynamic_cast<const Polygon*>(other);
	if (typeid(*shell)!=typeid(Geometry)) {
		return false;
	}
	Geometry* thisShell=dynamic_cast<Geometry *>(shell);
	if (typeid(*(otherPolygon->shell))!=typeid(Geometry)) {
		return false;
	}
	Geometry* otherPolygonShell=dynamic_cast<Geometry *>(otherPolygon->shell);
	if (!shell->equalsExact(otherPolygonShell, tolerance)) {
		return false;
	}
	if (holes->size()!=otherPolygon->holes->size()) {
		return false;
	}
	for (unsigned int i = 0; i < holes->size(); i++) {
		if (typeid(*(*holes)[i])!=typeid(Geometry)) {
			return false;
		}
		if (typeid(*((*(otherPolygon->holes))[i]))!=typeid(Geometry)) {
			return false;
		}
		if (!((LinearRing *)(*holes)[i])->equalsExact((*(otherPolygon->holes))[i],tolerance)) {
			return false;
		}
	}
	return true;
}

void Polygon::apply_ro(CoordinateFilter *filter) const {
	shell->apply_ro(filter);
	for (unsigned int i = 0; i < holes->size(); i++) {
		((LinearRing *)(*holes)[i])->apply_ro(filter);
	}
}

void Polygon::apply_rw(CoordinateFilter *filter) {
	shell->apply_rw(filter);
	for (unsigned int i = 0; i < holes->size(); i++) {
		((LinearRing *)(*holes)[i])->apply_rw(filter);
	}
}

void Polygon::apply_rw(GeometryFilter *filter) {
	filter->filter_rw(this);
}

void Polygon::apply_ro(GeometryFilter *filter) const {
	filter->filter_ro(this);
}

Geometry* Polygon::convexHull() const {
	return getExteriorRing()->convexHull();
}

void Polygon::normalize() {
	normalize(shell, true);
	for (unsigned int i = 0; i < holes->size(); i++) {
		normalize((LinearRing *)(*holes)[i], false);
	}
	sort(holes->begin(),holes->end(),greaterThen);
}

int Polygon::compareToSameClass(const Geometry *p) const {
	return shell->compareToSameClass(((Polygon*)p)->shell);
}

void Polygon::normalize(LinearRing *ring, bool clockwise) {
	if (ring->isEmpty()) {
		return;
	}
	CoordinateList* uniqueCoordinates=ring->getCoordinates();
	uniqueCoordinates->deleteAt(uniqueCoordinates->getSize()-1);
	const Coordinate* minCoordinate=CoordinateList::minCoordinate(ring->getCoordinates());
	CoordinateList::scroll(uniqueCoordinates, minCoordinate);
	uniqueCoordinates->add(uniqueCoordinates->getAt(0));
	ring->setPoints(uniqueCoordinates);
	if (cgAlgorithms->isCCW(ring->getCoordinates())==clockwise) {
		CoordinateList::reverse(ring->getCoordinates());
	}
}

const Coordinate* Polygon::getCoordinate() const {
	return shell->getCoordinate();
}

/**
*  Returns the area of this Polygon
*
*@return the area of the polygon
*/
double Polygon::getArea() const {
	double area=0.0;
	area+=fabs(CGAlgorithms::signedArea(shell->getCoordinates()));
	for(unsigned int i=0;i<holes->size();i++) {
        area-=fabs(CGAlgorithms::signedArea((*holes)[i]->getCoordinates()));
	}
	return area;
}

/**
*  Returns the perimeter of this Polygon
*
*@return the perimeter of the polygon
*/
double Polygon::getLength() const {
	double len=0.0;
	len+=shell->getLength();
	for(unsigned int i=0;i<holes->size();i++) {
        len+=(*holes)[i]->getLength();
	}
	return len;
}

void Polygon::apply_ro(GeometryComponentFilter *filter) const {
	filter->filter_ro(this);
	shell->apply_ro(filter);
	for(unsigned int i=0;i<holes->size();i++) {
        	(*holes)[i]->apply_ro(filter);
	}
}

void Polygon::apply_rw(GeometryComponentFilter *filter) {
	filter->filter_rw(this);
	shell->apply_rw(filter);
	for(unsigned int i=0;i<holes->size();i++) {
        	(*holes)[i]->apply_rw(filter);
	}
}

Polygon::~Polygon(){
	delete shell;
	for(int i=0;i<(int)holes->size();i++) {
		delete (*holes)[i];
	}
	delete holes;
}
}

<commit_msg>Memory leaks fixed. Partially due to getCoordinates() and GeometryCollection() changes, partially old dated.<commit_after>#include "../headers/geom.h"
#include <typeinfo>
#include "../headers/geosAlgorithm.h"

namespace geos {

Polygon::Polygon(){
	shell=new LinearRing();
	holes=new vector<Geometry *>();
}
Polygon::Polygon(const Polygon &p): Geometry(p.precisionModel, p.SRID){
	shell=new LinearRing(*p.shell);
	holes=new vector<Geometry *>();
	for(int i=0;i<(int)p.holes->size();i++) {
		LinearRing *h=new LinearRing(* (LinearRing*)(*p.holes)[i]);
		holes->push_back(h);
	}
}

Polygon::Polygon(LinearRing *newShell, PrecisionModel* precisionModel, int SRID): Geometry(precisionModel, SRID) {
	if (newShell==NULL)
		newShell=new LinearRing(CoordinateListFactory::internalFactory->createCoordinateList(), precisionModel, SRID);
	holes=new vector<Geometry *>();
	if (hasNullElements(holes)) {
		delete newShell;
		delete holes;
		throw new IllegalArgumentException("holes must not contain null elements");
	}
	if (newShell->isEmpty() && hasNonEmptyElements(holes)) {
		delete newShell;
		delete holes;
		throw new IllegalArgumentException("shell is empty but holes are not");
	}
	shell=newShell;
}

Polygon::Polygon(LinearRing *newShell, vector<Geometry *> *newHoles,
				 PrecisionModel* precisionModel, int SRID):
				Geometry(precisionModel, SRID) {
	if (newShell==NULL)
		newShell=new LinearRing(CoordinateListFactory::internalFactory->createCoordinateList(), precisionModel, SRID);

	if (newHoles==NULL)
		newHoles=new vector<Geometry *>();

	if (hasNullElements(newHoles)) {
		delete newShell;
		delete newHoles;
		throw new IllegalArgumentException("holes must not contain null elements");
	}
	if (newShell->isEmpty() && hasNonEmptyElements(newHoles)) {
		delete newShell;
		delete newHoles;
		throw new IllegalArgumentException("shell is empty but holes are not");
	}
	shell=newShell;
	holes=newHoles;
}

CoordinateList* Polygon::getCoordinates() const {
	if (isEmpty()) {
		return CoordinateListFactory::internalFactory->createCoordinateList();
	}
	CoordinateList *coordinates=CoordinateListFactory::internalFactory->createCoordinateList(getNumPoints());
	int k = -1;
	CoordinateList* shellCoordinates=shell->getCoordinates();
	for (int x = 0; x < shellCoordinates->getSize(); x++) {
		k++;
		coordinates->setAt(shellCoordinates->getAt(x),k);
	}
	delete shellCoordinates;
	for (unsigned int i = 0; i < holes->size(); i++) {
		CoordinateList* childCoordinates=((LinearRing *)(*holes)[i])->getCoordinates();
		for (int j = 0; j < childCoordinates->getSize(); j++) {
			k++;
			coordinates->setAt(childCoordinates->getAt(j),k);
		}
		delete childCoordinates;
	}
	return coordinates;
}

int Polygon::getNumPoints() const {
	int numPoints = shell->getNumPoints();
	for (unsigned int i = 0; i < holes->size(); i++) {
		numPoints += ((LinearRing *)(*holes)[i])->getNumPoints();
	}
	return numPoints;
}

int Polygon::getDimension() const {
	return 2;
}

int Polygon::getBoundaryDimension() const {
	return 1;
}

bool Polygon::isEmpty() const {
	return shell->isEmpty();
}

bool Polygon::isSimple() const {
	return true;
}

const LineString* Polygon::getExteriorRing() const {
	return shell;
}

int Polygon::getNumInteriorRing() const {
	return (int)holes->size();
}

const LineString* Polygon::getInteriorRingN(int n) const {
	return (LineString *) (*holes)[n];
}

string Polygon::getGeometryType() const {
	return "Polygon";
}

// Returns a newly allocated Geometry object
Geometry* Polygon::getBoundary() const {
	if (isEmpty()) {
		return new GeometryCollection(NULL, precisionModel, SRID);
	}
	vector<Geometry *> *rings=new vector<Geometry *>(holes->size() + 1);
	(*rings)[0]=new LineString(*shell);
	for (unsigned int i=0; i<holes->size(); i++) {
		(*rings)[i + 1] =new LineString(*(LineString*)(*holes)[i]);
	}
	MultiLineString *ret = new MultiLineString(rings, precisionModel, SRID);
	delete rings;
	return ret;
}

Envelope* Polygon::computeEnvelopeInternal() const {
	return shell->getEnvelopeInternal();
}

bool Polygon::equalsExact(const Geometry *other, double tolerance) const {
	if (!isEquivalentClass(other)) {
		return false;
	}
	const Polygon* otherPolygon=dynamic_cast<const Polygon*>(other);
	if (typeid(*shell)!=typeid(Geometry)) {
		return false;
	}
	Geometry* thisShell=dynamic_cast<Geometry *>(shell);
	if (typeid(*(otherPolygon->shell))!=typeid(Geometry)) {
		return false;
	}
	Geometry* otherPolygonShell=dynamic_cast<Geometry *>(otherPolygon->shell);
	if (!shell->equalsExact(otherPolygonShell, tolerance)) {
		return false;
	}
	if (holes->size()!=otherPolygon->holes->size()) {
		return false;
	}
	for (unsigned int i = 0; i < holes->size(); i++) {
		if (typeid(*(*holes)[i])!=typeid(Geometry)) {
			return false;
		}
		if (typeid(*((*(otherPolygon->holes))[i]))!=typeid(Geometry)) {
			return false;
		}
		if (!((LinearRing *)(*holes)[i])->equalsExact((*(otherPolygon->holes))[i],tolerance)) {
			return false;
		}
	}
	return true;
}

void Polygon::apply_ro(CoordinateFilter *filter) const {
	shell->apply_ro(filter);
	for (unsigned int i = 0; i < holes->size(); i++) {
		((LinearRing *)(*holes)[i])->apply_ro(filter);
	}
}

void Polygon::apply_rw(CoordinateFilter *filter) {
	shell->apply_rw(filter);
	for (unsigned int i = 0; i < holes->size(); i++) {
		((LinearRing *)(*holes)[i])->apply_rw(filter);
	}
}

void Polygon::apply_rw(GeometryFilter *filter) {
	filter->filter_rw(this);
}

void Polygon::apply_ro(GeometryFilter *filter) const {
	filter->filter_ro(this);
}

Geometry* Polygon::convexHull() const {
	return getExteriorRing()->convexHull();
}

void Polygon::normalize() {
	normalize(shell, true);
	for (unsigned int i = 0; i < holes->size(); i++) {
		normalize((LinearRing *)(*holes)[i], false);
	}
	sort(holes->begin(),holes->end(),greaterThen);
}

int Polygon::compareToSameClass(const Geometry *p) const {
	return shell->compareToSameClass(((Polygon*)p)->shell);
}

void Polygon::normalize(LinearRing *ring, bool clockwise) {
	if (ring->isEmpty()) {
		return;
	}
	CoordinateList* uniqueCoordinates=ring->getCoordinates();
	uniqueCoordinates->deleteAt(uniqueCoordinates->getSize()-1);
	const Coordinate* minCoordinate=CoordinateList::minCoordinate(uniqueCoordinates);
	CoordinateList::scroll(uniqueCoordinates, minCoordinate);
	uniqueCoordinates->add(uniqueCoordinates->getAt(0));
	if (cgAlgorithms->isCCW(uniqueCoordinates)==clockwise) {
		CoordinateList::reverse(uniqueCoordinates);
	}
	ring->setPoints(uniqueCoordinates);
	delete(uniqueCoordinates);
}

const Coordinate* Polygon::getCoordinate() const {
	return shell->getCoordinate();
}

/**
*  Returns the area of this Polygon
*
*@return the area of the polygon
*/
double Polygon::getArea() const {
	double area=0.0;
	area+=fabs(CGAlgorithms::signedArea(shell->getCoordinates()));
	for(unsigned int i=0;i<holes->size();i++) {
        area-=fabs(CGAlgorithms::signedArea((*holes)[i]->getCoordinates()));
	}
	return area;
}

/**
*  Returns the perimeter of this Polygon
*
*@return the perimeter of the polygon
*/
double Polygon::getLength() const {
	double len=0.0;
	len+=shell->getLength();
	for(unsigned int i=0;i<holes->size();i++) {
        len+=(*holes)[i]->getLength();
	}
	return len;
}

void Polygon::apply_ro(GeometryComponentFilter *filter) const {
	filter->filter_ro(this);
	shell->apply_ro(filter);
	for(unsigned int i=0;i<holes->size();i++) {
        	(*holes)[i]->apply_ro(filter);
	}
}

void Polygon::apply_rw(GeometryComponentFilter *filter) {
	filter->filter_rw(this);
	shell->apply_rw(filter);
	for(unsigned int i=0;i<holes->size();i++) {
        	(*holes)[i]->apply_rw(filter);
	}
}

Polygon::~Polygon(){
	delete shell;
	for(int i=0;i<(int)holes->size();i++) {
		delete (*holes)[i];
	}
	delete holes;
}
}

<|endoftext|>


<commit_before>#include <iostream>
#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()
#include "io.h"

using namespace std;

/**
* @brief A short function description
*
* A more detailed function description
*/

int printRasterInfo(const char* pszFilename)
{
    GDALDataset *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );

    if( poDataset == NULL )
    {
        std::cout << "Dataset " << pszFilename << " could not be opened." << std::endl;
        return -1;
    }
    else
    {
        double adfGeoTransform[6];
        std::cout << " Driver: " << poDataset->GetDriver()->GetDescription() << "/" <<
                poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl;
        std::cout << " Size: " << poDataset->GetRasterXSize() << "x" << poDataset->GetRasterYSize() << "x" <<
                poDataset->GetRasterCount() << std::endl;
        if( poDataset->GetProjectionRef()  != NULL )
            std::cout << " Projection: " << poDataset->GetProjectionRef() << std::endl;
        if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
        {
            std::cout << " Origin: (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl;
            std::cout << " Pixel Size: (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << std::endl;
        }
    }
    return 0;
}

int readRaster(const char* pszFilename)
{
    CPLSetConfigOption("GTIFF_VIRTUAL_MEM_IO", "YES" );
    GDALDataset *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );

    if( poDataset == NULL )
    {
        std::cout << "Dataset " << pszFilename << " could not be opened." << std::endl;
        return -1;
    }
    else
    {
        GDALRasterBand  *poBand;
        int             nBlockXSize, nBlockYSize;
        int             bGotMin, bGotMax;
        double          adfMinMax[2];

        poBand = poDataset->GetRasterBand( 1 );
        poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );

        printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(poBand->GetRasterDataType()),
                GDALGetColorInterpretationName(
                        poBand->GetColorInterpretation()) );
        adfMinMax[0] = poBand->GetMinimum( &bGotMin );
        adfMinMax[1] = poBand->GetMaximum( &bGotMax );
        if( ! (bGotMin && bGotMax) )
            GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
        printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
        if( poBand->GetOverviewCount() > 0 )
            printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );
        if( poBand->GetColorTable() != NULL )
            printf( "Band has a color table with %d entries.\n",
                    poBand->GetColorTable()->GetColorEntryCount() );
    }
    return 0;
}<commit_msg>Add some more logging to readRaster()<commit_after>#include <iostream>
#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()
#include "io.h"

using namespace std;

/**
* @brief A short function description
*
* A more detailed function description
*/

int printRasterInfo(const char* pszFilename)
{
    GDALDataset *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );

    if( poDataset == NULL )
    {
        std::cout << "Dataset " << pszFilename << " could not be opened." << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Dataset: " << pszFilename << std::endl;
        double adfGeoTransform[6];
        std::cout << " Driver: " << poDataset->GetDriver()->GetDescription() << "/" <<
                poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl;
        std::cout << " Size: " << poDataset->GetRasterXSize() << "x" << poDataset->GetRasterYSize() << "x" <<
                poDataset->GetRasterCount() << std::endl;
        if( poDataset->GetProjectionRef()  != NULL )
            std::cout << " Projection: " << poDataset->GetProjectionRef() << std::endl;
        if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
        {
            std::cout << " Origin: (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl;
            std::cout << " Pixel Size: (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << std::endl;
        }
    }
    return 0;
}

int readRaster(const char* pszFilename)
{
    CPLSetConfigOption("GTIFF_VIRTUAL_MEM_IO", "YES" );
    GDALDataset *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );

    if( poDataset == NULL )
    {
        std::cout << "Dataset " << pszFilename << " could not be opened." << std::endl;
        return -1;
    }
    else
    {
        GDALRasterBand  *poBand;
        int             nBlockXSize, nBlockYSize;
        int             bGotMin, bGotMax;
        double          adfMinMax[2];

        poBand = poDataset->GetRasterBand( 1 );
        poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );

        std::cout << "Dataset: " << pszFilename << std::endl;

        printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(poBand->GetRasterDataType()),
                GDALGetColorInterpretationName(
                        poBand->GetColorInterpretation()) );
        adfMinMax[0] = poBand->GetMinimum( &bGotMin );
        adfMinMax[1] = poBand->GetMaximum( &bGotMax );
        if( ! (bGotMin && bGotMax) )
            GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
        printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
        if( poBand->GetOverviewCount() > 0 )
            printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );
        if( poBand->GetColorTable() != NULL )
            printf( "Band has a color table with %d entries.\n",
                    poBand->GetColorTable()->GetColorEntryCount() );
        std::cout << std::endl;
    }
    return 0;
}<|endoftext|>


<commit_before>#include <arpc.h>
#include <chord_types.h>
#include <transport_prot.h>
#include "rpclib.h"

unsigned int rpclib_timeout (15);

static int dgram_fd = -1;
static ptr<axprt_dgram> dgram_xprt;

void
doRPCcb (xdrproc_t proc, dorpc_res *res, void *out, aclnt_cb cb, clnt_stat err);

ptr<aclnt>
get_aclnt (str host, unsigned short port)
{
  if (dgram_fd < 0) {
    dgram_fd = inetsocket (SOCK_DGRAM);
    if (dgram_fd < 0) fatal << "Failed to allocate dgram socket.\n";
    dgram_xprt = axprt_dgram::alloc (dgram_fd, sizeof(sockaddr), 230000);
    if (!dgram_xprt) fatal << "Failed to allocate dgram_xprt.\n";
  }

  sockaddr_in saddr;
  bzero(&saddr, sizeof(sockaddr_in));
  saddr.sin_family = AF_INET;
  inet_aton (host.cstr (), &saddr.sin_addr);
  saddr.sin_port = htons (port);

  ptr<aclnt> c = aclnt::alloc (dgram_xprt, transport_program_1,
			       (sockaddr *)&(saddr));

  return c;
}

void
doRPC (const chord_node &n, const rpc_program &prog,
       int procno, const void *in, void *out, aclnt_cb cb)
{
  ptr<aclnt> c = get_aclnt (n.r.hostname, n.r.port);
  if (c == NULL)
    fatal << "Couldn't get aclnt for " << n.r.hostname << "\n";

  //form the transport RPC
  ptr<dorpc_arg> arg = New refcounted<dorpc_arg> ();

  //header
  struct sockaddr_in saddr;
  bzero(&saddr, sizeof (sockaddr_in));
  saddr.sin_family = AF_INET;
  inet_aton (n.r.hostname.cstr (), &saddr.sin_addr);

  arg->dest.machine_order_ipv4_addr = ntohl (saddr.sin_addr.s_addr);
  arg->dest.machine_order_port_vnnum = (n.r.port << 16) | n.vnode_num;
  //leave coords as random.
  bzero (&arg->src, sizeof (arg->src));
  arg->progno = prog.progno;
  arg->procno = procno;

  //marshall the args ourself
  xdrproc_t inproc = prog.tbl[procno].xdr_arg;
  xdrproc_t outproc = prog.tbl[procno].xdr_res;
  assert (outproc);

  xdrsuio x (XDR_ENCODE);
  if ((!inproc) || (!inproc (x.xdrp (), (void *)in))) {
    fatal << "failed to marshall args\n";
  } else {
    int args_len = x.uio ()->resid ();
    arg->args.setsize (args_len);
    void *marshalled_args = suio_flatten (x.uio ());
    memcpy (arg->args.base (), marshalled_args, args_len);
    free (marshalled_args);

    dorpc_res *res = New dorpc_res (DORPC_OK);
    c->timedcall (rpclib_timeout, TRANSPORTPROC_DORPC, arg, res,
		  wrap (&doRPCcb, outproc, res, out, cb));
  }
}

void
doRPCcb (xdrproc_t proc, dorpc_res *res, void *out, aclnt_cb cb, clnt_stat err)
{
  xdrmem x ((char *)res->resok->results.base (),
	    res->resok->results.size (), XDR_DECODE);

  if (err) {
    warnx << "doRPC: err = " << err << "\n";
  } else if (!proc (x.xdrp (), out)) {
    warnx << "failed to unmarshall result\n";
    cb (RPC_CANTSEND);
    return;
  }

  cb (err);
  delete res;
}
<commit_msg>Valgrind nit: initialize all fields of dorpc_arg.<commit_after>#include <arpc.h>
#include <chord_types.h>
#include <transport_prot.h>
#include "rpclib.h"

unsigned int rpclib_timeout (15);

static int dgram_fd = -1;
static ptr<axprt_dgram> dgram_xprt;

void
doRPCcb (xdrproc_t proc, dorpc_res *res, void *out, aclnt_cb cb, clnt_stat err);

ptr<aclnt>
get_aclnt (str host, unsigned short port)
{
  if (dgram_fd < 0) {
    dgram_fd = inetsocket (SOCK_DGRAM);
    if (dgram_fd < 0) fatal << "Failed to allocate dgram socket.\n";
    dgram_xprt = axprt_dgram::alloc (dgram_fd, sizeof(sockaddr), 230000);
    if (!dgram_xprt) fatal << "Failed to allocate dgram_xprt.\n";
  }

  sockaddr_in saddr;
  bzero(&saddr, sizeof(sockaddr_in));
  saddr.sin_family = AF_INET;
  inet_aton (host.cstr (), &saddr.sin_addr);
  saddr.sin_port = htons (port);

  ptr<aclnt> c = aclnt::alloc (dgram_xprt, transport_program_1,
			       (sockaddr *)&(saddr));

  return c;
}

void
doRPC (const chord_node &n, const rpc_program &prog,
       int procno, const void *in, void *out, aclnt_cb cb)
{
  ptr<aclnt> c = get_aclnt (n.r.hostname, n.r.port);
  if (c == NULL)
    fatal << "Couldn't get aclnt for " << n.r.hostname << "\n";

  //form the transport RPC
  ptr<dorpc_arg> arg = New refcounted<dorpc_arg> ();
  bzero (arg, sizeof (*arg));

  //header
  struct sockaddr_in saddr;
  bzero (&saddr, sizeof (sockaddr_in));
  saddr.sin_family = AF_INET;
  inet_aton (n.r.hostname.cstr (), &saddr.sin_addr);

  arg->dest.machine_order_ipv4_addr = ntohl (saddr.sin_addr.s_addr);
  arg->dest.machine_order_port_vnnum = (n.r.port << 16) | n.vnode_num;
  arg->progno = prog.progno;
  arg->procno = procno;

  //marshall the args ourself
  xdrproc_t inproc = prog.tbl[procno].xdr_arg;
  xdrproc_t outproc = prog.tbl[procno].xdr_res;
  assert (outproc);

  xdrsuio x (XDR_ENCODE);
  if ((!inproc) || (!inproc (x.xdrp (), (void *)in))) {
    fatal << "failed to marshall args\n";
  } else {
    int args_len = x.uio ()->resid ();
    arg->args.setsize (args_len);
    void *marshalled_args = suio_flatten (x.uio ());
    memcpy (arg->args.base (), marshalled_args, args_len);
    free (marshalled_args);

    dorpc_res *res = New dorpc_res (DORPC_OK);
    c->timedcall (rpclib_timeout, TRANSPORTPROC_DORPC, arg, res,
		  wrap (&doRPCcb, outproc, res, out, cb));
  }
}

void
doRPCcb (xdrproc_t proc, dorpc_res *res, void *out, aclnt_cb cb, clnt_stat err)
{
  xdrmem x ((char *)res->resok->results.base (),
	    res->resok->results.size (), XDR_DECODE);

  if (err) {
    warnx << "doRPC: err = " << err << "\n";
  } else if (!proc (x.xdrp (), out)) {
    warnx << "failed to unmarshall result\n";
    cb (RPC_CANTSEND);
    return;
  }

  cb (err);
  delete res;
}
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/*
 * Copyright (C) 2014 FFLAS-FFACK group
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 * Brice Boyer (briceboyer) <boyer.brice@gmail.com>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_ffpack_fgetrs_INL
#define __FFLASFFPACK_ffpack_fgetrs_INL

namespace FFPACK {

	template <class Field>
	void
	fgetrs (const Field& F,
		const FFLAS::FFLAS_SIDE Side,
		const size_t M, const size_t N, const size_t R,
		typename Field::Element_ptr A, const size_t lda,
		const size_t *P, const size_t *Q,
		typename Field::Element_ptr B, const size_t ldb,
		int * info)
	{

		*info =0;
		if (Side == FFLAS::FflasLeft) { // Left looking solve A X = B

			solveLB2 (F, FFLAS::FflasLeft, M, N, R, A, lda, Q, B, ldb);

			applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
				N, 0,(int) R, B, ldb, Q);

			bool consistent = true;
			for (size_t i = R; i < M; ++i)
				for (size_t j = 0; j < N; ++j)
					if (!F.isZero (*(B + i*ldb + j)))
						consistent = false;
			if (!consistent) {
				std::cerr<<"System is inconsistent"<<std::endl;
				*info = 1;
			}
			// The last rows of B are now supposed to be 0
#if 0
			for (size_t i = R; i < M; ++i)
				for (size_t j = 0; j < N; ++j)
					*(B + i*ldb + j) = F.zero;
#endif

			ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
			       R, N, F.one, A, lda , B, ldb);

			applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
				N, 0,(int) R, B, ldb, P);

		}
		else { // Right Looking X A = B

			applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
				M, 0,(int) R, B, ldb, P);

			ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
			       M, R, F.one, A, lda , B, ldb);

			fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, M, N-R, R, F.one,
			       B, ldb, A+R, lda, F.mOne, B+R, ldb);

			bool consistent = true;
			for (size_t i = 0; i < M; ++i)
				for (size_t j = R; j < N; ++j)
					if (!F.isZero (*(B + i*ldb + j)))
						consistent = false;
			if (!consistent) {
				std::cerr<<"System is inconsistent"<<std::endl;
				*info = 1;
			}
			// The last cols of B are now supposed to be 0

			applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
				M, 0,(int) R, B, ldb, Q);

			solveLB2 (F, FFLAS::FflasRight, M, N, R, A, lda, Q, B, ldb);
		}
	}

	template <class Field>
	typename Field::Element_ptr
	fgetrs (const Field& F,
		const FFLAS::FFLAS_SIDE Side,
		const size_t M, const size_t N, const size_t NRHS, const size_t R,
		typename Field::Element_ptr A, const size_t lda,
		const size_t *P, const size_t *Q,
		typename Field::Element_ptr X, const size_t ldx,
		typename Field::ConstElement_ptr B, const size_t ldb,
		int * info)
	{
		*info =0;
		typename Field::Element_ptr W;
		size_t ldw;

		if (Side == FFLAS::FflasLeft) { // Left looking solve A X = B

			// Initializing X to 0 (to be optimized)
			FFLAS::fzero(F,N,NRHS,X,ldx);
			// for (size_t i = 0; i <N; ++i)
			// for (size_t j=0; j< NRHS; ++j)
			// F.assign (*(X+i*ldx+j), F.zero);

			if (M > N){ // Cannot copy B into X
				W = FFLAS::fflas_new (F, M, NRHS);
				ldw = NRHS;
				FFLAS::fassign(F,M,NRHS,B,ldb,W,ldw);

				solveLB2 (F, FFLAS::FflasLeft, M, NRHS, R, A, lda, Q, W, ldw);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, W, ldw, Q);

				bool consistent = true;
				for (size_t i = R; i < M; ++i)
					for (size_t j = 0; j < NRHS; ++j)
						if (!F.isZero (*(W + i*ldw + j)))
							consistent = false;
				if (!consistent) {
					std::cerr<<"System is inconsistent"<<std::endl;
					*info = 1;
					FFLAS::fflas_delete (W);
					return X;
				}
				// Here the last rows of W are supposed to be 0

				ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       R, NRHS, F.one, A, lda , W, ldw);

				FFLAS::fassign(F,R,NRHS,W,ldw,X,ldx);

				FFLAS::fflas_delete (W);
				applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);

			}
			else { // Copy B to X directly

				FFLAS::fassign(F,M,NRHS,B,ldb,X,ldx);

				solveLB2 (F, FFLAS::FflasLeft, M, NRHS, R, A, lda, Q, X, ldx);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				bool consistent = true;
				for (size_t i = R; i < M; ++i)
					for (size_t j = 0; j < NRHS; ++j)
						if (!F.isZero (*(X + i*ldx + j)))
							consistent = false;
				if (!consistent) {
					std::cerr<<"System is inconsistent"<<std::endl;
					*info = 1;
					return X;
				}
				// Here the last rows of W are supposed to be 0

				ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       R, NRHS, F.one, A, lda , X, ldx);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);
			}
			return X;

		}
		else { // Right Looking X A = B

			FFLAS::fzero(F,NRHS,M,X,ldx);
			// for (size_t i = 0; i <NRHS; ++i)
			// for (size_t j=0; j< M; ++j)
			// F.assign (*(X+i*ldx+j), F.zero);

			if (M < N) {
				W = FFLAS::fflas_new (F, NRHS, N);
				ldw = N;
				FFLAS::fassign (F,NRHS, N, B, ldb, W, ldw);

				applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
					NRHS, 0,(int) R, W, ldw, P);

				ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       NRHS, R, F.one, A, lda , W, ldw);

				fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, NRHS, N-R, R, F.one,
				       W, ldw, A+R, lda, F.mOne, W+R, ldw);

				bool consistent = true;
				for (size_t i = 0; i < NRHS; ++i)
					for (size_t j = R; j < N; ++j)
						if (!F.isZero (*(W + i*ldw + j)))
							consistent = false;
				if (!consistent) {
					std::cerr<<"System is inconsistent"<<std::endl;
					*info = 1;
					FFLAS::fflas_delete (W);
					return X;
				}
				// The last N-R cols of W are now supposed to be 0
				FFLAS::fassign (F, NRHS,R,  W , ldb, X ,ldx);
				FFLAS::fflas_delete (W);
				applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				solveLB2 (F, FFLAS::FflasRight, NRHS, M, R, A, lda, Q, X, ldx);

			}
			else { // M >=N
				FFLAS::fassign(F,NRHS,N,B,ldb,X,ldx);

				applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);

				ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       NRHS, R, F.one, A, lda , X, ldx);

				fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, NRHS, N-R, R, F.one,
				       X, ldx, A+R, lda, F.mOne, X+R, ldx);

				bool consistent = true;
				for (size_t i = 0; i < NRHS; ++i)
					for (size_t j = R; j < N; ++j)
						if (!F.isZero (*(X + i*ldx + j)))
							consistent = false;
				if (!consistent) {
					std::cerr<<"System is inconsistent"<<std::endl;
					*info = 1;
					return X;
				}
				// The last N-R cols of W are now supposed to be 0

				applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				solveLB2 (F, FFLAS::FflasRight, NRHS, M, R, A, lda, Q, X, ldx);

			}
			return X;
		}
	}

} // FFPACK

#endif // __FFLASFFPACK_ffpack_fgetrs_INL
<commit_msg>remove verbosity<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/*
 * Copyright (C) 2014 FFLAS-FFACK group
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 * Brice Boyer (briceboyer) <boyer.brice@gmail.com>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_ffpack_fgetrs_INL
#define __FFLASFFPACK_ffpack_fgetrs_INL

namespace FFPACK {

	template <class Field>
	void
	fgetrs (const Field& F,
		const FFLAS::FFLAS_SIDE Side,
		const size_t M, const size_t N, const size_t R,
		typename Field::Element_ptr A, const size_t lda,
		const size_t *P, const size_t *Q,
		typename Field::Element_ptr B, const size_t ldb,
		int * info)
	{

		*info =0;
		if (Side == FFLAS::FflasLeft) { // Left looking solve A X = B

			solveLB2 (F, FFLAS::FflasLeft, M, N, R, A, lda, Q, B, ldb);

			applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
				N, 0,(int) R, B, ldb, Q);

			bool consistent = true;
			for (size_t i = R; i < M; ++i)
				for (size_t j = 0; j < N; ++j)
					if (!F.isZero (*(B + i*ldb + j)))
						consistent = false;
			if (!consistent) {
				*info = 1;
			}
			// The last rows of B are now supposed to be 0
#if 0
			for (size_t i = R; i < M; ++i)
				for (size_t j = 0; j < N; ++j)
					*(B + i*ldb + j) = F.zero;
#endif

			ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
			       R, N, F.one, A, lda , B, ldb);

			applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
				N, 0,(int) R, B, ldb, P);

		}
		else { // Right Looking X A = B

			applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
				M, 0,(int) R, B, ldb, P);

			ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
			       M, R, F.one, A, lda , B, ldb);

			fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, M, N-R, R, F.one,
			       B, ldb, A+R, lda, F.mOne, B+R, ldb);

			bool consistent = true;
			for (size_t i = 0; i < M; ++i)
				for (size_t j = R; j < N; ++j)
					if (!F.isZero (*(B + i*ldb + j)))
						consistent = false;
			if (!consistent) {
				*info = 1;
			}
			// The last cols of B are now supposed to be 0

			applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
				M, 0,(int) R, B, ldb, Q);

			solveLB2 (F, FFLAS::FflasRight, M, N, R, A, lda, Q, B, ldb);
		}
	}

	template <class Field>
	typename Field::Element_ptr
	fgetrs (const Field& F,
		const FFLAS::FFLAS_SIDE Side,
		const size_t M, const size_t N, const size_t NRHS, const size_t R,
		typename Field::Element_ptr A, const size_t lda,
		const size_t *P, const size_t *Q,
		typename Field::Element_ptr X, const size_t ldx,
		typename Field::ConstElement_ptr B, const size_t ldb,
		int * info)
	{
		*info =0;
		typename Field::Element_ptr W;
		size_t ldw;

		if (Side == FFLAS::FflasLeft) { // Left looking solve A X = B

			// Initializing X to 0 (to be optimized)
			FFLAS::fzero(F,N,NRHS,X,ldx);
			// for (size_t i = 0; i <N; ++i)
			// for (size_t j=0; j< NRHS; ++j)
			// F.assign (*(X+i*ldx+j), F.zero);

			if (M > N){ // Cannot copy B into X
				W = FFLAS::fflas_new (F, M, NRHS);
				ldw = NRHS;
				FFLAS::fassign(F,M,NRHS,B,ldb,W,ldw);

				solveLB2 (F, FFLAS::FflasLeft, M, NRHS, R, A, lda, Q, W, ldw);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, W, ldw, Q);

				bool consistent = true;
				for (size_t i = R; i < M; ++i)
					for (size_t j = 0; j < NRHS; ++j)
						if (!F.isZero (*(W + i*ldw + j)))
							consistent = false;
				if (!consistent) {
					*info = 1;
					FFLAS::fflas_delete (W);
					return X;
				}
				// Here the last rows of W are supposed to be 0

				ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       R, NRHS, F.one, A, lda , W, ldw);

				FFLAS::fassign(F,R,NRHS,W,ldw,X,ldx);

				FFLAS::fflas_delete (W);
				applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);

			}
			else { // Copy B to X directly

				FFLAS::fassign(F,M,NRHS,B,ldb,X,ldx);

				solveLB2 (F, FFLAS::FflasLeft, M, NRHS, R, A, lda, Q, X, ldx);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				bool consistent = true;
				for (size_t i = R; i < M; ++i)
					for (size_t j = 0; j < NRHS; ++j)
						if (!F.isZero (*(X + i*ldx + j)))
							consistent = false;
				if (!consistent) {
					*info = 1;
					return X;
				}
				// Here the last rows of W are supposed to be 0

				ftrsm (F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       R, NRHS, F.one, A, lda , X, ldx);

				applyP (F, FFLAS::FflasLeft, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);
			}
			return X;

		}
		else { // Right Looking X A = B

			FFLAS::fzero(F,NRHS,M,X,ldx);
			// for (size_t i = 0; i <NRHS; ++i)
			// for (size_t j=0; j< M; ++j)
			// F.assign (*(X+i*ldx+j), F.zero);

			if (M < N) {
				W = FFLAS::fflas_new (F, NRHS, N);
				ldw = N;
				FFLAS::fassign (F,NRHS, N, B, ldb, W, ldw);

				applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
					NRHS, 0,(int) R, W, ldw, P);

				ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       NRHS, R, F.one, A, lda , W, ldw);

				fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, NRHS, N-R, R, F.one,
				       W, ldw, A+R, lda, F.mOne, W+R, ldw);

				bool consistent = true;
				for (size_t i = 0; i < NRHS; ++i)
					for (size_t j = R; j < N; ++j)
						if (!F.isZero (*(W + i*ldw + j)))
							consistent = false;
				if (!consistent) {
					*info = 1;
					FFLAS::fflas_delete (W);
					return X;
				}
				// The last N-R cols of W are now supposed to be 0
				FFLAS::fassign (F, NRHS,R,  W , ldb, X ,ldx);
				FFLAS::fflas_delete (W);
				applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				solveLB2 (F, FFLAS::FflasRight, NRHS, M, R, A, lda, Q, X, ldx);

			}
			else { // M >=N
				FFLAS::fassign(F,NRHS,N,B,ldb,X,ldx);

				applyP (F, FFLAS::FflasRight, FFLAS::FflasTrans,
					NRHS, 0,(int) R, X, ldx, P);

				ftrsm (F, FFLAS::FflasRight, FFLAS::FflasUpper, FFLAS::FflasNoTrans, FFLAS::FflasNonUnit,
				       NRHS, R, F.one, A, lda , X, ldx);

				fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, NRHS, N-R, R, F.one,
				       X, ldx, A+R, lda, F.mOne, X+R, ldx);

				bool consistent = true;
				for (size_t i = 0; i < NRHS; ++i)
					for (size_t j = R; j < N; ++j)
						if (!F.isZero (*(X + i*ldx + j)))
							consistent = false;
				if (!consistent) {
					*info = 1;
					return X;
				}
				// The last N-R cols of W are now supposed to be 0

				applyP (F, FFLAS::FflasRight, FFLAS::FflasNoTrans,
					NRHS, 0,(int) R, X, ldx, Q);

				solveLB2 (F, FFLAS::FflasRight, NRHS, M, R, A, lda, Q, X, ldx);

			}
			return X;
		}
	}

} // FFPACK

#endif // __FFLASFFPACK_ffpack_fgetrs_INL
<|endoftext|>


<commit_before>#include "dhash_common.h"
#include "dhash.h"
#include "verify.h"
#include <dbfe.h>
#include <sfscrypt.h>
#include <dhash_prot.h>
#include <chord.h>
#include <chord_types.h>
#include <chord_util.h>

bool
verify (chordID key, dhash_ctype t, char *buf, int len)
{
  switch (t)
    {
    case DHASH_CONTENTHASH:
      return verify_content_hash (key, buf, len);
      break;
    case DHASH_KEYHASH:
      return verify_key_hash (key, buf, len);
      break;
    case DHASH_DNSSEC: // XXX should be punted.
    case DHASH_NOAUTH:
    case DHASH_APPEND:
      return true;
      break;
    default:
      warn << "bad type " << t << "\n";
      return false;
    }
  return false;
}

bool
verify_content_hash (chordID key, char *buf, int len)
{
  char hashbytes[sha1::hashsize];
  sha1_hash (hashbytes, buf, len);
  chordID ID;
  mpz_set_rawmag_be (&ID, hashbytes, sizeof (hashbytes));  // For big endian
  return (ID == key);
}

bool
verify_key_hash (chordID key, char *buf, int len)
{
  // extract the public key from the message
  sfs_pubkey2 pubkey;
  sfs_sig2 sig;

  long contentlen;
  long v;
  xdrmem x1 (buf, (unsigned)len, XDR_DECODE);

  if (!xdr_sfs_pubkey2 (&x1, &pubkey)) return false;
  if (!xdr_sfs_sig2 (&x1, &sig)) return false;
  if (!XDR_GETLONG (&x1, &v)) return false;
  if (!XDR_GETLONG (&x1, &contentlen)) return false;

  char *content;
  if (!(content = (char *)XDR_INLINE (&x1, contentlen)))
      return false;

  ptr<sfspub> pk = sfscrypt.alloc (pubkey, SFS_VERIFY);

  // verify that public key hashes to ID
  strbuf b;
  pk->export_pubkey (b, false);
  str pk_raw = b;
  chordID hash = compute_hash (pk_raw.cstr (), pk_raw.len ());
  if (hash != key) return false;

  // verify signature
  str msg (content, contentlen);
  bool ok = pk->verify (sig, msg);

  return ok;
}

ptr<dhash_block>
get_block_contents (ptr<dbrec> d, dhash_ctype t)
{
  return get_block_contents (d->value, d->len, t);
}

ptr<dhash_block>
get_block_contents (ref<dbrec> d, dhash_ctype t)
{
  return get_block_contents (d->value, d->len, t);
}

ptr<dhash_block>
get_block_contents (ptr<dhash_block> block, dhash_ctype t)
{
  return get_block_contents (block->data, block->len, t);
}

ptr<dhash_block>
get_block_contents (char *data, unsigned int len, dhash_ctype t)
{
  // XXX make this function shorter...
  long version = 0;
  char *content;
  long contentlen = len;

  xdrmem x1 (data, len, XDR_DECODE);

  switch (t) {
  case DHASH_KEYHASH:
    {
      sfs_pubkey2 k;
      sfs_sig2 s;
      if (!xdr_sfs_pubkey2 (&x1, &k) || !xdr_sfs_sig2 (&x1, &s))
	return NULL;
      if (!XDR_GETLONG (&x1, &version))
	return NULL;
      if (!XDR_GETLONG (&x1, &contentlen))
	return NULL;
    }
    /* FALL THROUGH */

  case DHASH_CONTENTHASH:
  case DHASH_NOAUTH:
  case DHASH_APPEND:
    {
      if (!(content = (char *)XDR_INLINE (&x1, contentlen)))
	return NULL;
    }
    break;

  default:
    return NULL;
  }

  ptr<dhash_block> d = New refcounted<dhash_block> (content, contentlen, t);
  d->version = version;
  return d;
}

long
keyhash_version (ptr<dhash_block> data)
{
  return keyhash_version (data->data, data->len);
}

long
keyhash_version (ref<dhash_block> data)
{
  return keyhash_version (data->data, data->len);
}

long
keyhash_version (ref<dbrec> data)
{
  return keyhash_version (data->value, data->len);
}

long
keyhash_version (ptr<dbrec> data)
{
  return keyhash_version (data->value, data->len);
}

long
keyhash_version (char *value, unsigned int len)
{
  xdrmem x1 (value, len, XDR_DECODE);
  sfs_pubkey2 k;
  sfs_sig2 s;
  if (!xdr_sfs_pubkey2 (&x1, &k) || !xdr_sfs_sig2 (&x1, &s))
    return -1;
  long v;
  if (!XDR_GETLONG (&x1, &v))
    return -1;
  return v;
}

<commit_msg>fix problem with 0-length retrieves<commit_after>#include "dhash_common.h"
#include "dhash.h"
#include "verify.h"
#include <dbfe.h>
#include <sfscrypt.h>
#include <dhash_prot.h>
#include <chord.h>
#include <chord_types.h>
#include <chord_util.h>

bool
verify (chordID key, dhash_ctype t, char *buf, int len)
{
  switch (t)
    {
    case DHASH_CONTENTHASH:
      return verify_content_hash (key, buf, len);
      break;
    case DHASH_KEYHASH:
      return verify_key_hash (key, buf, len);
      break;
    case DHASH_DNSSEC: // XXX should be punted.
    case DHASH_NOAUTH:
    case DHASH_APPEND:
      return true;
      break;
    default:
      warn << "bad type " << t << "\n";
      return false;
    }
  return false;
}

bool
verify_content_hash (chordID key, char *buf, int len)
{
  char hashbytes[sha1::hashsize];
  sha1_hash (hashbytes, buf, len);
  chordID ID;
  mpz_set_rawmag_be (&ID, hashbytes, sizeof (hashbytes));  // For big endian
  return (ID == key);
}

bool
verify_key_hash (chordID key, char *buf, int len)
{
  // extract the public key from the message
  sfs_pubkey2 pubkey;
  sfs_sig2 sig;

  long contentlen;
  long v;
  xdrmem x1 (buf, (unsigned)len, XDR_DECODE);

  if (!xdr_sfs_pubkey2 (&x1, &pubkey)) return false;
  if (!xdr_sfs_sig2 (&x1, &sig)) return false;
  if (!XDR_GETLONG (&x1, &v)) return false;
  if (!XDR_GETLONG (&x1, &contentlen)) return false;

  char *content;
  if (!(content = (char *)XDR_INLINE (&x1, contentlen)))
      return false;

  ptr<sfspub> pk = sfscrypt.alloc (pubkey, SFS_VERIFY);

  // verify that public key hashes to ID
  strbuf b;
  pk->export_pubkey (b, false);
  str pk_raw = b;
  chordID hash = compute_hash (pk_raw.cstr (), pk_raw.len ());
  if (hash != key) return false;

  // verify signature
  str msg (content, contentlen);
  bool ok = pk->verify (sig, msg);

  return ok;
}

ptr<dhash_block>
get_block_contents (ptr<dbrec> d, dhash_ctype t)
{
  return get_block_contents (d->value, d->len, t);
}

ptr<dhash_block>
get_block_contents (ref<dbrec> d, dhash_ctype t)
{
  return get_block_contents (d->value, d->len, t);
}

ptr<dhash_block>
get_block_contents (ptr<dhash_block> block, dhash_ctype t)
{
  return get_block_contents (block->data, block->len, t);
}

ptr<dhash_block>
get_block_contents (char *data, unsigned int len, dhash_ctype t)
{
  // XXX make this function shorter...
  long version = 0;
  char *content;
  long contentlen = len;

  xdrmem x1 (data, len, XDR_DECODE);

  switch (t) {
  case DHASH_KEYHASH:
    {
      sfs_pubkey2 k;
      sfs_sig2 s;
      if (!xdr_sfs_pubkey2 (&x1, &k) || !xdr_sfs_sig2 (&x1, &s))
	return NULL;
      if (!XDR_GETLONG (&x1, &version))
	return NULL;
      if (!XDR_GETLONG (&x1, &contentlen))
	return NULL;
    }
    /* FALL THROUGH */

  case DHASH_CONTENTHASH:
  case DHASH_NOAUTH:
  case DHASH_APPEND:
    {
      if (len && !(content = (char *)XDR_INLINE (&x1, contentlen)))
	return NULL;
    }
    break;

  default:
    return NULL;
  }

  ptr<dhash_block> d = New refcounted<dhash_block> (content, contentlen, t);
  d->version = version;
  return d;
}

long
keyhash_version (ptr<dhash_block> data)
{
  return keyhash_version (data->data, data->len);
}

long
keyhash_version (ref<dhash_block> data)
{
  return keyhash_version (data->data, data->len);
}

long
keyhash_version (ref<dbrec> data)
{
  return keyhash_version (data->value, data->len);
}

long
keyhash_version (ptr<dbrec> data)
{
  return keyhash_version (data->value, data->len);
}

long
keyhash_version (char *value, unsigned int len)
{
  xdrmem x1 (value, len, XDR_DECODE);
  sfs_pubkey2 k;
  sfs_sig2 s;
  if (!xdr_sfs_pubkey2 (&x1, &k) || !xdr_sfs_sig2 (&x1, &s))
    return -1;
  long v;
  if (!XDR_GETLONG (&x1, &v))
    return -1;
  return v;
}

<|endoftext|>


<commit_before>#pragma once
#include <windows.h>
#include <wchar.h>

// Formats a message string using the specified message and variable
// list of arguments.
// must be LocalFree(pBuffer);
LPWSTR GetSystemErrorMessage(DWORD dw_error_code)
{
	LPWSTR pBuffer = NULL;
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_ALLOCATE_BUFFER,
		NULL,
		dw_error_code,
		0,
		(LPWSTR)&pBuffer,
		0,
		NULL);

	return pBuffer;
}

void report_error(LPWSTR pszFunction, DWORD dwError = GetLastError())
{
	wchar_t szMessage[4096] = { 0 };
	const wchar_t * p_system_error = GetSystemErrorMessage(dwError);
	int len = swprintf_s(szMessage, ARRAYSIZE(szMessage),
		L"%s failed w/err %d\n%s", pszFunction, dwError, p_system_error);
	//GetFormattedMessage
	MessageBox(NULL, (len != -1) ? szMessage : pszFunction,L"An error occurred!", MB_ICONERROR);

}<commit_msg>add free FormatMessageW buffer<commit_after>#pragma once
#include <windows.h>
#include <wchar.h>

// Formats a message string using the specified message and variable
// list of arguments.
// must be LocalFree(pBuffer);
LPWSTR GetSystemErrorMessage(DWORD dw_error_code)
{
	LPWSTR pBuffer = NULL;
	FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_ALLOCATE_BUFFER,
		NULL,
		dw_error_code,
		0,
		(LPWSTR)&pBuffer,
		0,
		NULL);

	return pBuffer;
}

void report_error(LPWSTR pszFunction, DWORD dwError = GetLastError())
{
	wchar_t szMessage[4096] = { 0 };
	const wchar_t * p_system_error = GetSystemErrorMessage(dwError);
	int len = swprintf_s(szMessage, ARRAYSIZE(szMessage),
		L"%s failed w/err %d\n%s", pszFunction, dwError, p_system_error);
	//GetFormattedMessage
	MessageBoxW(NULL, (len != -1) ? szMessage : pszFunction,L"An error occurred!", MB_ICONERROR);
	if (p_system_error != NULL)
	{
		LocalFree((void*)p_system_error);
	}
}<|endoftext|>