<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief cap constraint
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "CapConstraint.h"
#include "Utils/transactions.h"
#include "VocBase/document-collection.h"
#include "VocBase/transaction.h"

using namespace triagens::arango;

// -----------------------------------------------------------------------------
// --SECTION--                                               class CapConstraint
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief minimum size
////////////////////////////////////////////////////////////////////////////////

int64_t const CapConstraint::MinSize = 16384;

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

CapConstraint::CapConstraint (TRI_idx_iid_t iid,
                              TRI_document_collection_t* collection,
                              size_t count,
                              int64_t size)
  : Index(iid, std::vector<std::string>()),
    _collection(collection),
    _count(count),
    _size(static_cast<int64_t>(size)) {

  initialize();
}

CapConstraint::~CapConstraint () {
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

size_t CapConstraint::memory () const {
  return 0;
}

triagens::basics::Json CapConstraint::toJson (TRI_memory_zone_t* zone) const {
  auto json = Index::toJson(zone);

  json("size",     triagens::basics::Json(zone, static_cast<double>(_count)))
      ("byteSize", triagens::basics::Json(zone, static_cast<double>(_size)));

  return json;
}

int CapConstraint::insert (TRI_doc_mptr_t const*,
                           bool) {
  return TRI_ERROR_NO_ERROR;
}

int CapConstraint::remove (TRI_doc_mptr_t const*,
                           bool) {
  return TRI_ERROR_NO_ERROR;
}

int CapConstraint::postInsert (TRI_transaction_collection_t* trxCollection,
                               TRI_doc_mptr_t const*) {
  TRI_ASSERT(_count > 0 || _size > 0);

  return apply(trxCollection->_collection->_collection, trxCollection);
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief initialize the cap constraint
////////////////////////////////////////////////////////////////////////////////

int CapConstraint::initialize () {
  TRI_ASSERT(_count > 0 || _size > 0);

  TRI_headers_t* headers = _collection->_headersPtr;  // ONLY IN INDEX (CAP)
  int64_t currentCount   = static_cast<int64_t>(headers->count());
  int64_t currentSize    = headers->size();

  if ((_count > 0 && currentCount <= _count) &&
      (_size > 0 && currentSize <= _size)) {
    // nothing to do
    return TRI_ERROR_NO_ERROR;
  }
  else {
    TRI_vocbase_t* vocbase = _collection->_vocbase;
    TRI_voc_cid_t cid = _collection->_info._cid;

    triagens::arango::SingleCollectionWriteTransaction<UINT64_MAX> trx(new triagens::arango::StandaloneTransactionContext(), vocbase, cid);
    trx.addHint(TRI_TRANSACTION_HINT_LOCK_NEVER, false);
    trx.addHint(TRI_TRANSACTION_HINT_NO_BEGIN_MARKER, false);
    trx.addHint(TRI_TRANSACTION_HINT_NO_ABORT_MARKER, false);
    trx.addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION, false); // this is actually not true, but necessary to create trx id 0

    int res = trx.begin();

    if (res != TRI_ERROR_NO_ERROR) {
      return res;
    }

    TRI_transaction_collection_t* trxCollection = trx.trxCollection();
    res = apply(_collection, trxCollection);

    res = trx.finish(res);

    return res;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief apply the cap constraint for the collection
////////////////////////////////////////////////////////////////////////////////

int CapConstraint::apply (TRI_document_collection_t* document,
                          TRI_transaction_collection_t* trxCollection) {
  TRI_headers_t* headers = document->_headersPtr;  // PROTECTED by trx in trxCollection
  int64_t currentCount   = static_cast<int64_t>(headers->count());
  int64_t currentSize    = headers->size();

  int res = TRI_ERROR_NO_ERROR;

  // delete while at least one of the constraints is still violated
  while ((_count > 0 && currentCount > _count) ||
         (_size > 0 && currentSize > _size)) {
    TRI_doc_mptr_t* oldest = headers->front();

    if (oldest != nullptr) {
      TRI_ASSERT(oldest->getDataPtr() != nullptr);  // ONLY IN INDEX, PROTECTED by RUNTIME
      size_t oldSize = ((TRI_df_marker_t*) (oldest->getDataPtr()))->_size;  // ONLY IN INDEX, PROTECTED by RUNTIME

      TRI_ASSERT(oldSize > 0);

      if (trxCollection != nullptr) {
        res = TRI_DeleteDocumentDocumentCollection(trxCollection, nullptr, oldest);

        if (res != TRI_ERROR_NO_ERROR) {
          LOG_WARNING("cannot cap collection: %s", TRI_errno_string(res));
          break;
        }
      }
      else {
        headers->unlink(oldest);
      }

      currentCount--;
      currentSize -= (int64_t) oldSize;
    }
    else {
      // we should not get here
      LOG_WARNING("logic error in %s", __FUNCTION__);
      break;
    }
  }

  return res;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>fixed cap constraints<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief cap constraint
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "CapConstraint.h"
#include "Utils/transactions.h"
#include "VocBase/document-collection.h"
#include "VocBase/transaction.h"

using namespace triagens::arango;

// -----------------------------------------------------------------------------
// --SECTION--                                               class CapConstraint
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief minimum size
////////////////////////////////////////////////////////////////////////////////

int64_t const CapConstraint::MinSize = 16384;

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

CapConstraint::CapConstraint (TRI_idx_iid_t iid,
                              TRI_document_collection_t* collection,
                              size_t count,
                              int64_t size)
  : Index(iid, std::vector<std::string>()),
    _collection(collection),
    _count(count),
    _size(static_cast<int64_t>(size)) {

  initialize();
}

CapConstraint::~CapConstraint () {
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

size_t CapConstraint::memory () const {
  return 0;
}

triagens::basics::Json CapConstraint::toJson (TRI_memory_zone_t* zone) const {
  auto json = Index::toJson(zone);

  json("size",     triagens::basics::Json(zone, static_cast<double>(_count)))
      ("byteSize", triagens::basics::Json(zone, static_cast<double>(_size)));

  return json;
}

int CapConstraint::insert (TRI_doc_mptr_t const* doc,
                           bool) {
  if (_size > 0) {
    // there is a size restriction
    auto marker = static_cast<TRI_df_marker_t const*>(doc->getDataPtr());  // ONLY IN INDEX, PROTECTED by RUNTIME

    // check if the document would be too big
    if (static_cast<int64_t>(marker->_size) > _size) {
      return TRI_ERROR_ARANGO_DOCUMENT_TOO_LARGE;
    }
  }

  return TRI_ERROR_NO_ERROR;
}

int CapConstraint::remove (TRI_doc_mptr_t const*,
                           bool) {
  return TRI_ERROR_NO_ERROR;
}

int CapConstraint::postInsert (TRI_transaction_collection_t* trxCollection,
                               TRI_doc_mptr_t const*) {
  TRI_ASSERT(_count > 0 || _size > 0);

  return apply(trxCollection->_collection->_collection, trxCollection);
}

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief initialize the cap constraint
////////////////////////////////////////////////////////////////////////////////

int CapConstraint::initialize () {
  TRI_ASSERT(_count > 0 || _size > 0);

  TRI_headers_t* headers = _collection->_headersPtr;  // ONLY IN INDEX (CAP)
  int64_t currentCount   = static_cast<int64_t>(headers->count());
  int64_t currentSize    = headers->size();

  if ((_count > 0 && currentCount <= _count) &&
      (_size > 0 && currentSize <= _size)) {
    // nothing to do
    return TRI_ERROR_NO_ERROR;
  }
  else {
    TRI_vocbase_t* vocbase = _collection->_vocbase;
    TRI_voc_cid_t cid = _collection->_info._cid;

    triagens::arango::SingleCollectionWriteTransaction<UINT64_MAX> trx(new triagens::arango::StandaloneTransactionContext(), vocbase, cid);
    trx.addHint(TRI_TRANSACTION_HINT_LOCK_NEVER, false);
    trx.addHint(TRI_TRANSACTION_HINT_NO_BEGIN_MARKER, false);
    trx.addHint(TRI_TRANSACTION_HINT_NO_ABORT_MARKER, false);
    trx.addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION, false); // this is actually not true, but necessary to create trx id 0

    int res = trx.begin();

    if (res != TRI_ERROR_NO_ERROR) {
      return res;
    }

    TRI_transaction_collection_t* trxCollection = trx.trxCollection();
    res = apply(_collection, trxCollection);

    res = trx.finish(res);

    return res;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief apply the cap constraint for the collection
////////////////////////////////////////////////////////////////////////////////

int CapConstraint::apply (TRI_document_collection_t* document,
                          TRI_transaction_collection_t* trxCollection) {
  TRI_headers_t* headers = document->_headersPtr;  // PROTECTED by trx in trxCollection
  int64_t currentCount   = static_cast<int64_t>(headers->count());
  int64_t currentSize    = headers->size();

  int res = TRI_ERROR_NO_ERROR;

  // delete while at least one of the constraints is still violated
  while ((_count > 0 && currentCount > _count) ||
         (_size > 0 && currentSize > _size)) {
    TRI_doc_mptr_t* oldest = headers->front();

    if (oldest != nullptr) {
      TRI_ASSERT(oldest->getDataPtr() != nullptr);  // ONLY IN INDEX, PROTECTED by RUNTIME
      size_t oldSize = ((TRI_df_marker_t*) (oldest->getDataPtr()))->_size;  // ONLY IN INDEX, PROTECTED by RUNTIME

      TRI_ASSERT(oldSize > 0);

      if (trxCollection != nullptr) {
        res = TRI_DeleteDocumentDocumentCollection(trxCollection, nullptr, oldest);

        if (res != TRI_ERROR_NO_ERROR) {
          LOG_WARNING("cannot cap collection: %s", TRI_errno_string(res));
          break;
        }
      }
      else {
        headers->unlink(oldest);
      }

      currentCount--;
      currentSize -= (int64_t) oldSize;
    }
    else {
      // we should not get here
      LOG_WARNING("logic error in %s", __FUNCTION__);
      break;
    }
  }

  return res;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


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

#ifndef _SYSTEMSHELL_HXX_
#include "systemshell.hxx"
#endif

#include "osl/module.hxx"

const rtl::OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST = rtl::OUString::createFromAscii("add_to_recently_used_file_list");
const rtl::OUString LIB_RECENT_FILE = rtl::OUString::createFromAscii("librecentfile.so");

namespace SystemShell {

    typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const rtl::OUString&, const rtl::OUString&);

    //##############################
    rtl::OUString get_absolute_library_url(const rtl::OUString& lib_name)
    {
        rtl::OUString url;
        if (osl::Module::getUrlFromAddress(reinterpret_cast<oslGenericFunction>(AddToRecentDocumentList), url))
        {
            sal_Int32 index = url.lastIndexOf('/');
            url = url.copy(0, index + 1);
            url += LIB_RECENT_FILE;
        }
        return url;
    }

    //##############################
    void AddToRecentDocumentList(const rtl::OUString& aFileUrl, const rtl::OUString& aMimeType)
    {
        rtl::OUString librecentfile_url = get_absolute_library_url(LIB_RECENT_FILE);

        if (librecentfile_url.getLength())
        {
            osl::Module module(librecentfile_url);

            if (module.is())
            {
               // convert from reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>
               // not allowed in gcc 3.3 without permissive.
                PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list =
                    reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>(module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST));

                if (add_to_recently_used_file_list)
                    add_to_recently_used_file_list(aFileUrl, aMimeType);
            }
        }
    }

} // namespace SystemShell

<commit_msg>INTEGRATION: CWS warnings01 (1.5.14); FILE MERGED 2005/10/26 15:08:25 pl 1.5.14.1: #i55991# remove warnings for solaris platform<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: systemshell.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 14:20:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SYSTEMSHELL_HXX_
#include "systemshell.hxx"
#endif

#include "osl/module.hxx"

const rtl::OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST = rtl::OUString::createFromAscii("add_to_recently_used_file_list");
const rtl::OUString LIB_RECENT_FILE = rtl::OUString::createFromAscii("librecentfile.so");

namespace SystemShell {

    typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const rtl::OUString&, const rtl::OUString&);

    //##############################
    rtl::OUString get_absolute_library_url(const rtl::OUString& /*lib_name*/)
    {
        rtl::OUString url;
        if (osl::Module::getUrlFromAddress(reinterpret_cast<oslGenericFunction>(AddToRecentDocumentList), url))
        {
            sal_Int32 index = url.lastIndexOf('/');
            url = url.copy(0, index + 1);
            url += LIB_RECENT_FILE;
        }
        return url;
    }

    //##############################
    void AddToRecentDocumentList(const rtl::OUString& aFileUrl, const rtl::OUString& aMimeType)
    {
        rtl::OUString librecentfile_url = get_absolute_library_url(LIB_RECENT_FILE);

        if (librecentfile_url.getLength())
        {
            osl::Module module(librecentfile_url);

            if (module.is())
            {
               // convert from reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>
               // not allowed in gcc 3.3 without permissive.
                PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list =
                    reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>(module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST));

                if (add_to_recently_used_file_list)
                    add_to_recently_used_file_list(aFileUrl, aMimeType);
            }
        }
    }

} // namespace SystemShell

<|endoftext|>


<commit_before>#include <QtCore/QDebug>
#include <QtCore/QTimer>

#include <QtDBus/QtDBus>

#include <QtTest/QtTest>

#include <TelepathyQt4/ChannelFactory>
#include <TelepathyQt4/Connection>
#include <TelepathyQt4/ContactFactory>
#include <TelepathyQt4/ContactSearchChannel>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/Debug>

#include <telepathy-glib/debug.h>

#include <tests/lib/glib/echo/conn.h>
#include <tests/lib/glib/contact-search-chan.h>
#include <tests/lib/test.h>

using namespace Tp;

class TestContactSearchChan : public Test
{
    Q_OBJECT

public:
    TestContactSearchChan(QObject *parent = 0)
        : Test(parent),
          mConnService(0), mBaseConnService(0),
          mChan1Service(0)
    { }

protected Q_SLOTS:
    void onSearchStateChanged(Tp::ChannelContactSearchState state, const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details);
    void onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &result);

private Q_SLOTS:
    void initTestCase();
    void init();

    void testContactSearch();
    void testContactSearchEmptyResult();

    void cleanup();
    void cleanupTestCase();

private:
    ExampleEchoConnection *mConnService;
    TpBaseConnection *mBaseConnService;
    TpHandleRepoIface *mContactRepo;

    QString mConnName;
    QString mConnPath;
    ConnectionPtr mConn;
    ContactSearchChannelPtr mChan;
    ContactSearchChannelPtr mChan1;
    ContactSearchChannelPtr mChan2;

    QString mChan1Path;
    TpTestsContactSearchChannel *mChan1Service;
    QString mChan2Path;
    TpTestsContactSearchChannel *mChan2Service;

    ContactSearchChannel::SearchResult mSearchResult;

    struct SearchStateChangeInfo
    {
        SearchStateChangeInfo(ChannelContactSearchState state, const QString &errorName,
                const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
            : state(state), errorName(errorName), details(details)
        {
        }

        ChannelContactSearchState state;
        QString errorName;
        ContactSearchChannel::SearchStateChangeDetails details;
    };
    QList<SearchStateChangeInfo> mSearchStateChangeInfoList;
};

void TestContactSearchChan::onSearchStateChanged(Tp::ChannelContactSearchState state,
        const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
{
    mSearchStateChangeInfoList.append(SearchStateChangeInfo(state, errorName, details));
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchResultReceived(
        const Tp::ContactSearchChannel::SearchResult &result)
{
    QCOMPARE(mChan->searchState(), ChannelContactSearchStateInProgress);
    mSearchResult = result;
    mLoop->exit(0);
}

void TestContactSearchChan::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("contact-search-chan");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    gchar *name;
    gchar *connPath;
    GError *error = 0;

    mConnService = EXAMPLE_ECHO_CONNECTION(g_object_new(
            EXAMPLE_TYPE_ECHO_CONNECTION,
            "account", "me@example.com",
            "protocol", "example",
            NULL));
    QVERIFY(mConnService != 0);
    mBaseConnService = TP_BASE_CONNECTION(mConnService);
    QVERIFY(mBaseConnService != 0);

    QVERIFY(tp_base_connection_register(mBaseConnService,
                "example", &name, &connPath, &error));
    QVERIFY(error == 0);

    QVERIFY(name != 0);
    QVERIFY(connPath != 0);

    mConnName = QLatin1String(name);
    mConnPath = QLatin1String(connPath);

    g_free(name);
    g_free(connPath);

    mConn = Connection::create(mConnName, mConnPath,
            ChannelFactory::create(QDBusConnection::sessionBus()),
            ContactFactory::create());
    QCOMPARE(mConn->isReady(), false);

    QVERIFY(connect(mConn->requestConnect(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(), true);
    QCOMPARE(static_cast<uint>(mConn->status()),
             static_cast<uint>(Connection::StatusConnected));

    QByteArray chan1Path;
    mChan1Path = mConnPath + QLatin1String("/ContactSearchChannel/1");
    chan1Path = mChan1Path.toAscii();
    mChan1Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConnService,
                "object-path", chan1Path.data(),
                NULL));

    QByteArray chan2Path;
    mChan2Path = mConnPath + QLatin1String("/ContactSearchChannel/2");
    chan2Path = mChan2Path.toAscii();
    mChan2Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConnService,
                "object-path", chan2Path.data(),
                NULL));
}

void TestContactSearchChan::init()
{
    initImpl();
    mSearchResult.clear();
    mSearchStateChangeInfoList.clear();
}

void TestContactSearchChan::testContactSearch()
{
    mChan1 = ContactSearchChannel::create(mConn, mChan1Path, QVariantMap());
    mChan = mChan1;
    QVERIFY(connect(mChan1->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan1->isReady(), true);

    QCOMPARE(mChan1->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan1->limit(), static_cast<uint>(0));
    QCOMPARE(mChan1->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan1->availableSearchKeys().count(), 1);
    QCOMPARE(mChan1->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan1->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    mChan1->search(QLatin1String("employer"), QLatin1String("Collabora"));
    while (mChan1->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    QCOMPARE(mSearchResult.isEmpty(), false);
    QCOMPARE(mSearchResult.size(), 3);

    QStringList expectedIds;
    expectedIds << QLatin1String("oggis") << QLatin1String("andrunko") <<
        QLatin1String("wjt");
    expectedIds.sort();
    QStringList expectedFns;
    expectedFns << QLatin1String("Olli Salli") << QLatin1String("Andre Moreira Magalhaes") <<
        QLatin1String("Will Thompson");
    expectedFns.sort();
    QStringList ids;
    QStringList fns;
    for (ContactSearchChannel::SearchResult::const_iterator it = mSearchResult.constBegin();
                                                            it != mSearchResult.constEnd();
                                                            ++it)
    {
        QCOMPARE(it.key().isNull(), false);
        ids << it.key()->id();
        QCOMPARE(it.value().isValid(), true);
        QCOMPARE(it.value().allFields().isEmpty(), false);
        Q_FOREACH (const ContactInfoField &contactInfo, it.value().allFields()) {
            QCOMPARE(contactInfo.fieldName, QLatin1String("fn"));
            fns.append(contactInfo.fieldValue.first());
        }
    }
    ids.sort();
    QCOMPARE(ids, expectedIds);
    fns.sort();
    QCOMPARE(fns, expectedFns);

    mChan1.reset();
}

void TestContactSearchChan::testContactSearchEmptyResult()
{
    mChan2 = ContactSearchChannel::create(mConn, mChan2Path, QVariantMap());
    mChan = mChan2;
    QVERIFY(connect(mChan2->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan2->isReady(), true);

    QCOMPARE(mChan2->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan2->limit(), static_cast<uint>(0));
    QCOMPARE(mChan2->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan2->availableSearchKeys().count(), 1);
    QCOMPARE(mChan2->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan2->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    ContactSearchMap searchTerms;
    searchTerms.insert(QLatin1String("employer"), QLatin1String("FooBar"));
    mChan2->search(searchTerms);
    while (mChan2->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchResult.isEmpty(), true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    mChan2.reset();
}

void TestContactSearchChan::cleanup()
{
    cleanupImpl();
}

void TestContactSearchChan::cleanupTestCase()
{
    if (mConn) {
        // Disconnect and wait for the readiness change
        QVERIFY(connect(mConn->requestDisconnect(),
                        SIGNAL(finished(Tp::PendingOperation*)),
                        SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
        QCOMPARE(mLoop->exec(), 0);

        if (mConn->isValid()) {
            QVERIFY(connect(mConn.data(),
                            SIGNAL(invalidated(Tp::DBusProxy *,
                                               const QString &, const QString &)),
                            mLoop,
                            SLOT(quit())));
            QCOMPARE(mLoop->exec(), 0);
        }
    }

    if (mChan1Service != 0) {
        g_object_unref(mChan1Service);
        mChan1Service = 0;
    }

    if (mChan2Service != 0) {
        g_object_unref(mChan2Service);
        mChan2Service = 0;
    }

    if (mConnService != 0) {
        mBaseConnService = 0;
        g_object_unref(mConnService);
        mConnService = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestContactSearchChan)
#include "_gen/chan-contact-search.cpp.moc.hpp"
<commit_msg>chan-contact-search test: Test that the pending operation returned from search only finishes when the state changes.<commit_after>#include <QtCore/QDebug>
#include <QtCore/QTimer>

#include <QtDBus/QtDBus>

#include <QtTest/QtTest>

#include <TelepathyQt4/ChannelFactory>
#include <TelepathyQt4/Connection>
#include <TelepathyQt4/ContactFactory>
#include <TelepathyQt4/ContactSearchChannel>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/Debug>

#include <telepathy-glib/debug.h>

#include <tests/lib/glib/echo/conn.h>
#include <tests/lib/glib/contact-search-chan.h>
#include <tests/lib/test.h>

using namespace Tp;

class TestContactSearchChan : public Test
{
    Q_OBJECT

public:
    TestContactSearchChan(QObject *parent = 0)
        : Test(parent),
          mConnService(0), mBaseConnService(0),
          mChan1Service(0), mSearchReturned(false)
    { }

protected Q_SLOTS:
    void onSearchStateChanged(Tp::ChannelContactSearchState state, const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details);
    void onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &result);
    void onSearchReturned(Tp::PendingOperation *op);

private Q_SLOTS:
    void initTestCase();
    void init();

    void testContactSearch();
    void testContactSearchEmptyResult();

    void cleanup();
    void cleanupTestCase();

private:
    ExampleEchoConnection *mConnService;
    TpBaseConnection *mBaseConnService;
    TpHandleRepoIface *mContactRepo;

    QString mConnName;
    QString mConnPath;
    ConnectionPtr mConn;
    ContactSearchChannelPtr mChan;
    ContactSearchChannelPtr mChan1;
    ContactSearchChannelPtr mChan2;

    QString mChan1Path;
    TpTestsContactSearchChannel *mChan1Service;
    QString mChan2Path;
    TpTestsContactSearchChannel *mChan2Service;

    ContactSearchChannel::SearchResult mSearchResult;
    bool mSearchReturned;

    struct SearchStateChangeInfo
    {
        SearchStateChangeInfo(ChannelContactSearchState state, const QString &errorName,
                const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
            : state(state), errorName(errorName), details(details)
        {
        }

        ChannelContactSearchState state;
        QString errorName;
        ContactSearchChannel::SearchStateChangeDetails details;
    };
    QList<SearchStateChangeInfo> mSearchStateChangeInfoList;
};

void TestContactSearchChan::onSearchStateChanged(Tp::ChannelContactSearchState state,
        const QString &errorName,
        const Tp::ContactSearchChannel::SearchStateChangeDetails &details)
{
    mSearchStateChangeInfoList.append(SearchStateChangeInfo(state, errorName, details));
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchResultReceived(
        const Tp::ContactSearchChannel::SearchResult &result)
{
    QCOMPARE(mChan->searchState(), ChannelContactSearchStateInProgress);
    mSearchResult = result;
    mLoop->exit(0);
}

void TestContactSearchChan::onSearchReturned(Tp::PendingOperation *op)
{
    QCOMPARE(op->isError(), false);
    QVERIFY(mChan->searchState() != ChannelContactSearchStateNotStarted);
    mSearchReturned = true;
    mLoop->exit(0);
}

void TestContactSearchChan::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("contact-search-chan");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    gchar *name;
    gchar *connPath;
    GError *error = 0;

    mConnService = EXAMPLE_ECHO_CONNECTION(g_object_new(
            EXAMPLE_TYPE_ECHO_CONNECTION,
            "account", "me@example.com",
            "protocol", "example",
            NULL));
    QVERIFY(mConnService != 0);
    mBaseConnService = TP_BASE_CONNECTION(mConnService);
    QVERIFY(mBaseConnService != 0);

    QVERIFY(tp_base_connection_register(mBaseConnService,
                "example", &name, &connPath, &error));
    QVERIFY(error == 0);

    QVERIFY(name != 0);
    QVERIFY(connPath != 0);

    mConnName = QLatin1String(name);
    mConnPath = QLatin1String(connPath);

    g_free(name);
    g_free(connPath);

    mConn = Connection::create(mConnName, mConnPath,
            ChannelFactory::create(QDBusConnection::sessionBus()),
            ContactFactory::create());
    QCOMPARE(mConn->isReady(), false);

    QVERIFY(connect(mConn->requestConnect(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(), true);
    QCOMPARE(static_cast<uint>(mConn->status()),
             static_cast<uint>(Connection::StatusConnected));

    QByteArray chan1Path;
    mChan1Path = mConnPath + QLatin1String("/ContactSearchChannel/1");
    chan1Path = mChan1Path.toAscii();
    mChan1Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConnService,
                "object-path", chan1Path.data(),
                NULL));

    QByteArray chan2Path;
    mChan2Path = mConnPath + QLatin1String("/ContactSearchChannel/2");
    chan2Path = mChan2Path.toAscii();
    mChan2Service = TP_TESTS_CONTACT_SEARCH_CHANNEL(g_object_new(
                TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
                "connection", mConnService,
                "object-path", chan2Path.data(),
                NULL));
}

void TestContactSearchChan::init()
{
    initImpl();
    mSearchResult.clear();
    mSearchStateChangeInfoList.clear();
    mSearchReturned = false;
}

void TestContactSearchChan::testContactSearch()
{
    mChan1 = ContactSearchChannel::create(mConn, mChan1Path, QVariantMap());
    mChan = mChan1;
    QVERIFY(connect(mChan1->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan1->isReady(), true);

    QCOMPARE(mChan1->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan1->limit(), static_cast<uint>(0));
    QCOMPARE(mChan1->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan1->availableSearchKeys().count(), 1);
    QCOMPARE(mChan1->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan1->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan1.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    QVERIFY(connect(mChan1->search(QLatin1String("employer"), QLatin1String("Collabora")),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan1->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    QCOMPARE(mSearchResult.isEmpty(), false);
    QCOMPARE(mSearchResult.size(), 3);

    QStringList expectedIds;
    expectedIds << QLatin1String("oggis") << QLatin1String("andrunko") <<
        QLatin1String("wjt");
    expectedIds.sort();
    QStringList expectedFns;
    expectedFns << QLatin1String("Olli Salli") << QLatin1String("Andre Moreira Magalhaes") <<
        QLatin1String("Will Thompson");
    expectedFns.sort();
    QStringList ids;
    QStringList fns;
    for (ContactSearchChannel::SearchResult::const_iterator it = mSearchResult.constBegin();
                                                            it != mSearchResult.constEnd();
                                                            ++it)
    {
        QCOMPARE(it.key().isNull(), false);
        ids << it.key()->id();
        QCOMPARE(it.value().isValid(), true);
        QCOMPARE(it.value().allFields().isEmpty(), false);
        Q_FOREACH (const ContactInfoField &contactInfo, it.value().allFields()) {
            QCOMPARE(contactInfo.fieldName, QLatin1String("fn"));
            fns.append(contactInfo.fieldValue.first());
        }
    }
    ids.sort();
    QCOMPARE(ids, expectedIds);
    fns.sort();
    QCOMPARE(fns, expectedFns);

    mChan1.reset();
}

void TestContactSearchChan::testContactSearchEmptyResult()
{
    mChan2 = ContactSearchChannel::create(mConn, mChan2Path, QVariantMap());
    mChan = mChan2;
    QVERIFY(connect(mChan2->becomeReady(ContactSearchChannel::FeatureCore),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mChan2->isReady(), true);

    QCOMPARE(mChan2->searchState(), ChannelContactSearchStateNotStarted);
    QCOMPARE(mChan2->limit(), static_cast<uint>(0));
    QCOMPARE(mChan2->availableSearchKeys().isEmpty(), false);
    QCOMPARE(mChan2->availableSearchKeys().count(), 1);
    QCOMPARE(mChan2->availableSearchKeys().first(), QLatin1String("employer"));
    QCOMPARE(mChan2->server(), QLatin1String("characters.shakespeare.lit"));

    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &)),
                SLOT(onSearchStateChanged(Tp::ChannelContactSearchState, const QString &,
                        const Tp::ContactSearchChannel::SearchStateChangeDetails &))));
    QVERIFY(connect(mChan2.data(),
                SIGNAL(searchResultReceived(const Tp::ContactSearchChannel::SearchResult &)),
                SLOT(onSearchResultReceived(const Tp::ContactSearchChannel::SearchResult &))));

    ContactSearchMap searchTerms;
    searchTerms.insert(QLatin1String("employer"), QLatin1String("FooBar"));
    QVERIFY(connect(mChan2->search(searchTerms),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onSearchReturned(Tp::PendingOperation *))));
    while (!mSearchReturned) {
        QCOMPARE(mLoop->exec(), 0);
    }
    while (mChan2->searchState() != ChannelContactSearchStateCompleted) {
        QCOMPARE(mLoop->exec(), 0);
    }

    QCOMPARE(mSearchReturned, true);

    QCOMPARE(mSearchResult.isEmpty(), true);

    QCOMPARE(mSearchStateChangeInfoList.count(), 2);
    SearchStateChangeInfo info = mSearchStateChangeInfoList.at(0);
    QCOMPARE(info.state, ChannelContactSearchStateInProgress);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("in progress"));

    info = mSearchStateChangeInfoList.at(1);
    QCOMPARE(info.state, ChannelContactSearchStateCompleted);
    QCOMPARE(info.errorName, QLatin1String(""));
    QCOMPARE(info.details.hasDebugMessage(), true);
    QCOMPARE(info.details.debugMessage(), QLatin1String("completed"));

    mChan2.reset();
}

void TestContactSearchChan::cleanup()
{
    cleanupImpl();
}

void TestContactSearchChan::cleanupTestCase()
{
    if (mConn) {
        // Disconnect and wait for the readiness change
        QVERIFY(connect(mConn->requestDisconnect(),
                        SIGNAL(finished(Tp::PendingOperation*)),
                        SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
        QCOMPARE(mLoop->exec(), 0);

        if (mConn->isValid()) {
            QVERIFY(connect(mConn.data(),
                            SIGNAL(invalidated(Tp::DBusProxy *,
                                               const QString &, const QString &)),
                            mLoop,
                            SLOT(quit())));
            QCOMPARE(mLoop->exec(), 0);
        }
    }

    if (mChan1Service != 0) {
        g_object_unref(mChan1Service);
        mChan1Service = 0;
    }

    if (mChan2Service != 0) {
        g_object_unref(mChan2Service);
        mChan2Service = 0;
    }

    if (mConnService != 0) {
        mBaseConnService = 0;
        g_object_unref(mConnService);
        mConnService = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestContactSearchChan)
#include "_gen/chan-contact-search.cpp.moc.hpp"
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003 [NAMES_GO_HERE]
 *                    Massachusetts Institute of Technology
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "p2psim/network.h"
#include "p2psim/topology.h"
#include "protocols/protocolfactory.h"
#include "euclidean.h"
#include <cmath>
#include <iostream>
using namespace std;

Euclidean::Euclidean(vector<string>*)
{
}

Euclidean::~Euclidean()
{
}

Time
Euclidean::latency(IPAddress ip1x, IPAddress ip2x, bool reply)
{
  IPAddress ip1 = Network::Instance()->first_ip(ip1x);
  IPAddress ip2 = Network::Instance()->first_ip(ip2x);
  assert(ip1 > 0 && ip2 > 0);
  Coord c1 = _nodes[ip1];
  Coord c2 = _nodes[ip2];

  if (ip1==ip2)
    return 0;
  else {
    Time t= (Time) hypot(labs(c2.first - c1.first), labs(c2.second - c1.second));
    if (t > 1000)
      fprintf(stderr,"warning! %u,%u -> %u,%u\n",c1.first,c1.second,c2.first,c2.second);
    return t;
  }
}

void
Euclidean::parse(ifstream &ifs)
{
  string line;
  Time max_first, max_second;

  max_first = max_second = 0;
  while(getline(ifs,line)) {
    vector<string> words = split(line);

    // skip empty lines and commented lines
    if(words.empty() || words[0][0] == '#')
      continue;

    // nodeid, coordinates and at least one protocol
    if(words.size() < 2) {
      cerr << "provide nodeid and coordinates per line" << endl;
      continue;
    }

    // node-id
    IPAddress ipaddr = (IPAddress) strtoull(words[0].c_str(), NULL, 10);
    if(!ipaddr)
      cerr << "found node-id 0.  you're asking for trouble." << endl;

    // x,y coordinates
    vector<string> coords = split(words[1], ",");
    Coord c;
    if (coords.size () < 2) {
      cerr << "malformed coordinates " << endl;
      exit (-1);
    }
    c.first = atoi(coords[0].c_str());
    c.second = atoi(coords[1].c_str());
    if ((Time) c.first > max_first)
      max_first = c.first;
    else if ((Time) c.second > max_second)
      max_second = c.second;

    // what kind of node?
    Node *p = ProtocolFactory::Instance()->create(ipaddr);

    // add the new node it to the topology
    if(_nodes.find(p->ip()) != _nodes.end())
      cerr << "warning: node " << ipaddr << " already added! (" <<words[0]<<")" << endl;
    _nodes[p->ip()] = c;

    // add the node to the network
    send(Network::Instance()->nodechan(), &p);
  }

  _med_lat = (Time) sqrt((double) (max_first * max_first + max_second * max_second))/3;
}
<commit_msg>get rid of annoying warning message<commit_after>/*
 * Copyright (c) 2003 [NAMES_GO_HERE]
 *                    Massachusetts Institute of Technology
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "p2psim/network.h"
#include "p2psim/topology.h"
#include "protocols/protocolfactory.h"
#include "euclidean.h"
#include <cmath>
#include <iostream>
using namespace std;

Euclidean::Euclidean(vector<string>*)
{
}

Euclidean::~Euclidean()
{
}

Time
Euclidean::latency(IPAddress ip1x, IPAddress ip2x, bool reply)
{
  IPAddress ip1 = Network::Instance()->first_ip(ip1x);
  IPAddress ip2 = Network::Instance()->first_ip(ip2x);
  assert(ip1 > 0 && ip2 > 0);
  Coord c1 = _nodes[ip1];
  Coord c2 = _nodes[ip2];

  if (ip1==ip2)
    return 0;
  else {
    Time t= (Time) hypot(labs(c2.first - c1.first), labs(c2.second - c1.second));
    return t;
  }
}

void
Euclidean::parse(ifstream &ifs)
{
  string line;
  Time max_first, max_second;

  max_first = max_second = 0;
  while(getline(ifs,line)) {
    vector<string> words = split(line);

    // skip empty lines and commented lines
    if(words.empty() || words[0][0] == '#')
      continue;

    // nodeid, coordinates and at least one protocol
    if(words.size() < 2) {
      cerr << "provide nodeid and coordinates per line" << endl;
      continue;
    }

    // node-id
    IPAddress ipaddr = (IPAddress) strtoull(words[0].c_str(), NULL, 10);
    if(!ipaddr)
      cerr << "found node-id 0.  you're asking for trouble." << endl;

    // x,y coordinates
    vector<string> coords = split(words[1], ",");
    Coord c;
    if (coords.size () < 2) {
      cerr << "malformed coordinates " << endl;
      exit (-1);
    }
    c.first = atoi(coords[0].c_str());
    c.second = atoi(coords[1].c_str());
    if ((Time) c.first > max_first)
      max_first = c.first;
    else if ((Time) c.second > max_second)
      max_second = c.second;

    // what kind of node?
    Node *p = ProtocolFactory::Instance()->create(ipaddr);

    // add the new node it to the topology
    if(_nodes.find(p->ip()) != _nodes.end())
      cerr << "warning: node " << ipaddr << " already added! (" <<words[0]<<")" << endl;
    _nodes[p->ip()] = c;

    // add the node to the network
    send(Network::Instance()->nodechan(), &p);
  }

  _med_lat = (Time) sqrt((double) (max_first * max_first + max_second * max_second))/3;
}
<|endoftext|>


<commit_before><commit_msg>Unused return value warning fix<commit_after><|endoftext|>


<commit_before><commit_msg>Allows receivers of nullptr from begin_data to output any quantity of data.<commit_after><|endoftext|>


<commit_before>#include "WhistleControl.h"

using namespace naoth;

WhistleControl::WhistleControl():
  onOffSwitch(0),
  whistleListFile("whistles.lst"),
  activeChannels("1010")

{}

void WhistleControl::print(std::ostream& stream) const
{
  stream << "switch: " << (onOffSwitch == 1 ? "on" : "off") << std::endl;
  stream << "whistle list file: " << whistleListFile << std::endl;
  stream << "active channels(Left|Front|Right|Rear): " << activeChannels << std::endl;
}

WhistleControl::~WhistleControl()
{}

<commit_msg>initialize whistlecontrol variables<commit_after>#include "WhistleControl.h"

using namespace naoth;

WhistleControl::WhistleControl():
  onOffSwitch(0),
  whistleListFile("whistles.lst"),
  activeChannels("1010"),
  threshold(0.4),
  checkAllWhistles(true),
  saveRawAudio(false)
{}

void WhistleControl::print(std::ostream& stream) const
{
  stream << "switch: " << (onOffSwitch == 1 ? "on" : "off") << std::endl;
  stream << "whistle list file: " << whistleListFile << std::endl;
  stream << "active channels(Left|Front|Right|Rear): " << activeChannels << std::endl;
}

WhistleControl::~WhistleControl()
{}

<|endoftext|>


<commit_before>#include <string>

#include "../include/Account.h"

using namespace std;

static const string Account::admin = "AA";
static const string Account::sell  = "SS";
static const string Account::buy   = "BS";
static const string Account::full  = "FS";
static const double Account::maxPrice = 999999.99;

string Account::getType() {
    return this->type;
}

void Account::setType(string type) {
    this->type = type;
}

double Account::getBalance() {
    return this->balance;
}

void Account::setBalance(double balance) {
    this->balance = balance;
}

string Account::getUsername() {
    return this->username;
}

void Account::setUsername(string username) {
    this->username = username;
}
<commit_msg>FIXED: 'static' may not be used when defining (as opposed to declaring) a static data member<commit_after>#include <string>

#include "../include/Account.h"

using namespace std;

// ‘static’ may not be used when defining (as opposed to declaring) a static data member [-fpermissive]
const string Account::admin = "AA";
const string Account::sell  = "SS";
const string Account::buy   = "BS";
const string Account::full  = "FS";
const double Account::maxPrice = 999999.99;

string Account::getType() {
    return this->type;
}

void Account::setType(string type) {
    this->type = type;
}

double Account::getBalance() {
    return this->balance;
}

void Account::setBalance(double balance) {
    this->balance = balance;
}

string Account::getUsername() {
    return this->username;
}

void Account::setUsername(string username) {
    this->username = username;
}
<|endoftext|>


<commit_before>#include "LogicController.h"

LogicController::LogicController() {
    logicState = LOGIC_STATE_INTERRUPT;
    processState = PROCCESS_STATE_SEARCHING;

    prioritizedControllers = {
        PrioritizedController{0, (Controller*)(&searchController)},
        PrioritizedController{1, (Controller*)(&obstacleController)},
        PrioritizedController{2, (Controller*)(&pickUpController)}
    };

    control_queue = priority_queue<PrioritizedController>();

}

LogicController::~LogicController() {}

void LogicController::Reset() {

    logicState = LOGIC_STATE_INTERRUPT;
    processState = PROCCESS_STATE_SEARCHING;

    prioritizedControllers = {
        PrioritizedController{0, (Controller*)(&searchController)},
        PrioritizedController{1, (Controller*)(&obstacleController)},
        PrioritizedController{2, (Controller*)(&pickUpController)}
    };

    control_queue = priority_queue<PrioritizedController>();
}

Result LogicController::DoWork() {
    Result result;

    if (processState == PROCCESS_STATE_SEARCHING) {

    }
    else if (processState == PROCCESS_COLLECTING_TARGET) {

    }
    else if (processState  == PROCCESS_STATE_TARGET_PICKEDUP) {

    }

    switch(logicState) {
    case LOGIC_STATE_INTERRUPT: {

        //Reset the control queue
        control_queue = priority_queue<PrioritizedController>();

        for(PrioritizedController cntrlr : prioritizedControllers) {
            if(cntrlr.controller->ShouldInterrupt()) {
                control_queue.push(cntrlr);
            }
        }

        if(control_queue.empty()) {
            result.type = behavior;
            result.b = wait;

            return result;
        }

        result = control_queue.top().controller->DoWork();

        if(result.type == behavior) {
            if(result.b == nextProcess) {
                if (processState == _LAST) {
                    processState = _FIRST;
                }
                else {
                processState = (ProcessState)((int)processState + 1);
                }
            } else if(result.b == prevProcess) {
                if (processState == _FIRST) {
                    processState = (ProcessState)((int)_LAST - 1);
                }
                else {
                processState = (ProcessState)((int)processState - 1);
                }
            }
        } else if(result.type == precisionDriving) {

            logicState = LOGIC_STATE_PRECISION_COMMAND;

        } else if(result.type == waypoint) {

            logicState = LOGIC_STATE_WAITING;
            result = control_queue.top().controller->DoWork();

        }

        break;
    }

    case LOGIC_STATE_WAITING: {

        result = driveController.DoWork();
        if (result.type = behavior) {
            if(driveController.ShouldInterrupt()) {
                logicState = LOGIC_STATE_INTERRUPT;
            }
            else {
                return result;
            }
        }
        else {
            return result;
        }

        break;
    }

    case LOGIC_STATE_PRECISION_COMMAND: {

        result = control_queue.top().controller->DoWork();
        driveController.setResultData(result);
        result = driveController.DoWork();
        break;
    }
    }

    return result;
}

void LogicController::UpdateData() {

}

void LogicController::ProcessData() {

}

bool LogicController::ShouldInterrupt() {
    ProcessData();

    return false;
}

bool LogicController::HasWork() {
    return false;
}

void LogicController::controllerInterconnect() {

    if(pickUpController.GetIgnoreCenter()) {
        obstacleController.SetIgnoreCenter();
    }
}

void LogicController::setPositionData(Point currentLocation) {
    searchController.setCurrentLocation(currentLocation);
    dropOffController.SetCurrentLocation(currentLocation);
    obstacleController.SetCurrentLocation(currentLocation);
}

void LogicController::setMapPositionData(Point currentLocationMap) {

}

void LogicController::setVelocityData(float linearVelocity, float angularVelocity) {
    driveController.SetVelocityData(linearVelocity,angularVelocity);
}

void LogicController::setMapVelocityData(float linearVelocity, float angularVelocity) {

}

void LogicController::setAprilTags(vector<TagPoint> tags) {
    pickUpController.SetTagData(tags);
    obstacleController.SetTagData(tags);
    dropOffController.setTargetData(tags);
}

void LogicController::setSonarData(float left, float center, float right) {
    pickUpController.SetSonarData(center);
    obstacleController.SetSonarData(left,center,right);
}

void LogicController::setCenterLocationOdom(Point centerLocationOdom) {
    searchController.setCenterLocation(centerLocationOdom);
    dropOffController.SetCenterLocation(centerLocationOdom);
}

void LogicController::setCenterLocationMap(Point centerLocationMap) {

}
<commit_msg>Added alternet priorites based upon process loop state<commit_after>#include "LogicController.h"

LogicController::LogicController() {
    logicState = LOGIC_STATE_INTERRUPT;
    processState = PROCCESS_STATE_SEARCHING;

    prioritizedControllers = {
        PrioritizedController{0, (Controller*)(&searchController)},
        PrioritizedController{1, (Controller*)(&obstacleController)},
        PrioritizedController{2, (Controller*)(&pickUpController)},
        PrioritizedController{-1, (Controller*)(&dropOffController)}
    };

    control_queue = priority_queue<PrioritizedController>();

}

LogicController::~LogicController() {}

void LogicController::Reset() {

    logicState = LOGIC_STATE_INTERRUPT;
    processState = PROCCESS_STATE_SEARCHING;

    prioritizedControllers = {
        PrioritizedController{0, (Controller*)(&searchController)},
        PrioritizedController{1, (Controller*)(&obstacleController)},
        PrioritizedController{2, (Controller*)(&pickUpController)}
    };

    control_queue = priority_queue<PrioritizedController>();
}

Result LogicController::DoWork() {
    Result result;

    if (processState == PROCCESS_STATE_SEARCHING) {
        prioritizedControllers = {
            PrioritizedController{0, (Controller*)(&searchController)},
            PrioritizedController{1, (Controller*)(&obstacleController)},
            PrioritizedController{2, (Controller*)(&pickUpController)},
            PrioritizedController{-1, (Controller*)(&dropOffController)}
        };
    }
    else if (processState == PROCCESS_COLLECTING_TARGET) {
        prioritizedControllers = {
            PrioritizedController{-1, (Controller*)(&searchController)},
            PrioritizedController{1, (Controller*)(&obstacleController)},
            PrioritizedController{2, (Controller*)(&pickUpController)},
            PrioritizedController{-1, (Controller*)(&dropOffController)}
        };
    }
    else if (processState  == PROCCESS_STATE_TARGET_PICKEDUP) {
        prioritizedControllers = {
            PrioritizedController{-1, (Controller*)(&searchController)},
            PrioritizedController{2, (Controller*)(&obstacleController)},
            PrioritizedController{-1, (Controller*)(&pickUpController)},
            PrioritizedController{1, (Controller*)(&dropOffController)}
        };
    }

    switch(logicState) {
    case LOGIC_STATE_INTERRUPT: {

        //Reset the control queue
        control_queue = priority_queue<PrioritizedController>();

        for(PrioritizedController cntrlr : prioritizedControllers) {
            if(cntrlr.controller->ShouldInterrupt()) {
                if (cntrlr.priority < 0) {
                    continue;
                }
                else {
                    control_queue.push(cntrlr);
                }
            }
        }

        if(control_queue.empty()) {
            result.type = behavior;
            result.b = wait;

            return result;
        }

        result = control_queue.top().controller->DoWork();

        if(result.type == behavior) {
            if(result.b == nextProcess) {
                if (processState == _LAST) {
                    processState = _FIRST;
                }
                else {
                    processState = (ProcessState)((int)processState + 1);
                }
            } else if(result.b == prevProcess) {
                if (processState == _FIRST) {
                    processState = (ProcessState)((int)_LAST - 1);
                }
                else {
                    processState = (ProcessState)((int)processState - 1);
                }
            }
        } else if(result.type == precisionDriving) {

            logicState = LOGIC_STATE_PRECISION_COMMAND;

        } else if(result.type == waypoint) {

            logicState = LOGIC_STATE_WAITING;
            result = control_queue.top().controller->DoWork();

        }

        break;
    }

    case LOGIC_STATE_WAITING: {

        result = driveController.DoWork();
        if (result.type = behavior) {
            if(driveController.ShouldInterrupt()) {
                logicState = LOGIC_STATE_INTERRUPT;
            }
            else {
                return result;
            }
        }
        else {
            return result;
        }

        break;
    }

    case LOGIC_STATE_PRECISION_COMMAND: {

        result = control_queue.top().controller->DoWork();
        driveController.setResultData(result);
        result = driveController.DoWork();
        break;
    }
    }

    return result;
}

void LogicController::UpdateData() {

}

void LogicController::ProcessData() {

}

bool LogicController::ShouldInterrupt() {
    ProcessData();

    return false;
}

bool LogicController::HasWork() {
    return false;
}

void LogicController::controllerInterconnect() {

    if(pickUpController.GetIgnoreCenter()) {
        obstacleController.SetIgnoreCenter();
    }
}

void LogicController::setPositionData(Point currentLocation) {
    searchController.setCurrentLocation(currentLocation);
    dropOffController.SetCurrentLocation(currentLocation);
    obstacleController.SetCurrentLocation(currentLocation);
}

void LogicController::setMapPositionData(Point currentLocationMap) {

}

void LogicController::setVelocityData(float linearVelocity, float angularVelocity) {
    driveController.SetVelocityData(linearVelocity,angularVelocity);
}

void LogicController::setMapVelocityData(float linearVelocity, float angularVelocity) {

}

void LogicController::setAprilTags(vector<TagPoint> tags) {
    pickUpController.SetTagData(tags);
    obstacleController.SetTagData(tags);
    dropOffController.setTargetData(tags);
}

void LogicController::setSonarData(float left, float center, float right) {
    pickUpController.SetSonarData(center);
    obstacleController.SetSonarData(left,center,right);
}

void LogicController::setCenterLocationOdom(Point centerLocationOdom) {
    searchController.setCenterLocation(centerLocationOdom);
    dropOffController.SetCenterLocation(centerLocationOdom);
}

void LogicController::setCenterLocationMap(Point centerLocationMap) {

}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library 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 or 3 of the License.

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, see <http://www.gnu.org/licenses/>.
*/

#include "iodevicereader.h"
#include "qasyncreader.h"

#include "mediagraph.h"

#include <phonon/streaminterface.h>

#include <dshow.h>
#include <initguid.h>

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM

namespace Phonon
{
    namespace DS9
    {
        //these mediatypes define a stream, its type will be autodetected by DirectShow
        static QVector<AM_MEDIA_TYPE> getMediaTypes()
        {
            AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0};

            QVector<AM_MEDIA_TYPE> ret;
            //normal auto-detect stream
            ret << mt;
            //AVI stream
            mt.subtype = MEDIASUBTYPE_Avi;
            ret << mt;
            //WAVE stream
            mt.subtype = MEDIASUBTYPE_WAVE;
            ret << mt;
            return ret;
        }

        class StreamReader : public QAsyncReader, public Phonon::StreamInterface
        {
        public:
            StreamReader(QBaseFilter *parent, const Phonon::MediaSource &source, const MediaGraph *mg) :
              QAsyncReader(parent, getMediaTypes()),
                  m_seekable(false), m_pos(0), m_size(-1), m_mediaGraph(mg)
              {
                  connectToSource(source);
              }

              //for Phonon::StreamInterface
              void writeData(const QByteArray &data)
              {
                  m_pos += data.size();
                  m_buffer += data;
              }

              void endOfData()
              {
              }

              void setStreamSize(qint64 newSize)
              {
                  QMutexLocker locker(&m_mutex);
                  m_size = newSize;
              }

              void setStreamSeekable(bool s)
              {
                  QMutexLocker locker(&m_mutex);
                  m_seekable = s;
              }

              //virtual pure members

              //implementation from IAsyncReader
              STDMETHODIMP Length(LONGLONG *total, LONGLONG *available)
              {
                  QMutexLocker locker(&m_mutex);
                  if (total) {
                      *total = m_size;
                  }

                  if (available) {
                      *available = m_size;
                  }

                  return S_OK;
              }

              HRESULT read(LONGLONG pos, LONG length, BYTE *buffer, LONG *actual)
              {
                  Q_ASSERT(!m_mutex.tryLock());
                  if (m_mediaGraph->isStopping()) {
                      return VFW_E_WRONG_STATE;
                  }

                  if(m_size != 1 && pos + length > m_size) {
                      //it tries to read outside of the boundaries
                      return E_FAIL;
                  }

                  if (m_pos - m_buffer.size() != pos) {
                      if (!m_seekable) {
                          return S_FALSE;
                      }
                      m_pos = pos;
                      seekStream(pos);
                      m_buffer.clear();
                  }

                  int oldSize = m_buffer.size();
                  while (m_buffer.size() < int(length)) {
                      needData();
                      if (m_mediaGraph->isStopping()) {
                          return VFW_E_WRONG_STATE;
                      }

                      if (oldSize == m_buffer.size()) {
                          break; //we didn't get any data
                      }
                      oldSize = m_buffer.size();
                  }

                  int bytesRead = qMin(m_buffer.size(), int(length));
                  qMemCopy(buffer, m_buffer.data(), bytesRead);
                  //truncate the buffer
                  m_buffer = m_buffer.mid(bytesRead);

                  if (actual) {
                      *actual = bytesRead; //initialization
                  }

                  return bytesRead == length ? S_OK : S_FALSE;
              }

        public:
            //for Phonon::StreamInterface
            QByteArray m_buffer;
            bool m_seekable;
            qint64 m_pos;
            qint64 m_size;

            const MediaGraph *m_mediaGraph;
        };

        IODeviceReader::IODeviceReader(const Phonon::MediaSource &source, const MediaGraph *mg) :
        QBaseFilter(CLSID_NULL)
        {
            //create the output pin
            m_streamReader = new StreamReader(this, source, mg);
        }

        IODeviceReader::~IODeviceReader()
        {
        }
    }
}

#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM

QT_END_NAMESPACE
<commit_msg>Phonon: allows to stream wave files from QIODevice<commit_after>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library 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 or 3 of the License.

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, see <http://www.gnu.org/licenses/>.
*/

#include "iodevicereader.h"
#include "qasyncreader.h"

#include "mediagraph.h"

#include <phonon/streaminterface.h>

#include <dshow.h>
#include <initguid.h>

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM

namespace Phonon
{
    namespace DS9
    {
        //these mediatypes define a stream, its type will be autodetected by DirectShow
        static QVector<AM_MEDIA_TYPE> getMediaTypes()
        {
            //the order here is important because otherwise,
            //directshow might not be able to detect the stream type correctly

            AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_Avi, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0};

            QVector<AM_MEDIA_TYPE> ret;
            //AVI stream
            ret << mt;
            //WAVE stream
            mt.subtype = MEDIASUBTYPE_WAVE;
            ret << mt;
            //normal auto-detect stream (must be at the end!)
            mt.subtype = MEDIASUBTYPE_NULL;
            ret << mt;
            return ret;
        }

        class StreamReader : public QAsyncReader, public Phonon::StreamInterface
        {
        public:
            StreamReader(QBaseFilter *parent, const Phonon::MediaSource &source, const MediaGraph *mg) :
              QAsyncReader(parent, getMediaTypes()),
                  m_seekable(false), m_pos(0), m_size(-1), m_mediaGraph(mg)
              {
                  connectToSource(source);
              }

              //for Phonon::StreamInterface
              void writeData(const QByteArray &data)
              {
                  m_pos += data.size();
                  m_buffer += data;
              }

              void endOfData()
              {
              }

              void setStreamSize(qint64 newSize)
              {
                  QMutexLocker locker(&m_mutex);
                  m_size = newSize;
              }

              void setStreamSeekable(bool s)
              {
                  QMutexLocker locker(&m_mutex);
                  m_seekable = s;
              }

              //virtual pure members

              //implementation from IAsyncReader
              STDMETHODIMP Length(LONGLONG *total, LONGLONG *available)
              {
                  QMutexLocker locker(&m_mutex);
                  if (total) {
                      *total = m_size;
                  }

                  if (available) {
                      *available = m_size;
                  }

                  return S_OK;
              }

              HRESULT read(LONGLONG pos, LONG length, BYTE *buffer, LONG *actual)
              {
                  Q_ASSERT(!m_mutex.tryLock());
                  if (m_mediaGraph->isStopping()) {
                      return VFW_E_WRONG_STATE;
                  }

                  if(m_size != 1 && pos + length > m_size) {
                      //it tries to read outside of the boundaries
                      return E_FAIL;
                  }

                  if (m_pos - m_buffer.size() != pos) {
                      if (!m_seekable) {
                          return S_FALSE;
                      }
                      m_pos = pos;
                      seekStream(pos);
                      m_buffer.clear();
                  }

                  int oldSize = m_buffer.size();
                  while (m_buffer.size() < int(length)) {
                      needData();
                      if (m_mediaGraph->isStopping()) {
                          return VFW_E_WRONG_STATE;
                      }

                      if (oldSize == m_buffer.size()) {
                          break; //we didn't get any data
                      }
                      oldSize = m_buffer.size();
                  }

                  int bytesRead = qMin(m_buffer.size(), int(length));
                  qMemCopy(buffer, m_buffer.data(), bytesRead);
                  //truncate the buffer
                  m_buffer = m_buffer.mid(bytesRead);

                  if (actual) {
                      *actual = bytesRead; //initialization
                  }

                  return bytesRead == length ? S_OK : S_FALSE;
              }

        public:
            //for Phonon::StreamInterface
            QByteArray m_buffer;
            bool m_seekable;
            qint64 m_pos;
            qint64 m_size;

            const MediaGraph *m_mediaGraph;
        };

        IODeviceReader::IODeviceReader(const Phonon::MediaSource &source, const MediaGraph *mg) :
        QBaseFilter(CLSID_NULL)
        {
            //create the output pin
            m_streamReader = new StreamReader(this, source, mg);
        }

        IODeviceReader::~IODeviceReader()
        {
        }
    }
}

#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM

QT_END_NAMESPACE
<|endoftext|>


<commit_before>#include "opencv.hpp"
#include "utilities.hpp"
#include "AspectError.hpp"
#include <string>
#include <ctime>

struct HeaderData
{
    timespec captureTime, captureTimeMono;
    int cameraID;
    float cameraTemperature;
    int cpuTemperature;
    int i2c_temperatures[8];
    long frameCount;
    int exposure;
    timespec imageWriteTime;
    int preampGain;
    int analogGain;
    float sunCenter[2];
    float sunCenterError[2];
    int imageMinMax[2];
    float XYinterceptslope[4];
    double CTLsolution[2];
    float screenCenter[2];
    float screenCenterError[2];
    int fiducialCount;
    float fiducialX[10];
    float fiducialY[10];
    int limbCount;
    float limbX[10];
    float limbY[10];
    //float limbXerror[10];
    //float limbYerror[10];
    int fiducialIDX[10];
    int fiducialIDY[10];
    float cpuVoltage[5];
    bool isTracking;
    bool isOutputting;

    AspectCode runResult;

    float latitude;
    float longitude;
    float solarTarget[2];
    double northAngle;
    float clockingAngle;
};

int writePNGImage(cv::InputArray _image, const std::string fileName);
int writeFITSImage(cv::InputArray, HeaderData keys, const std::string fileName);
int readFITSImage(const std::string fileName, cv::OutputArray image);
int readFITSHeader(const std::string fileName, HeaderData &keys);
<commit_msg>removing utilities.hpp<commit_after>#include "opencv.hpp"
#include <string>
#include <ctime>

struct HeaderData
{
    timespec captureTime, captureTimeMono;
    int cameraID;
    float cameraTemperature;
    int cpuTemperature;
    int i2c_temperatures[8];
    long frameCount;
    int exposure;
    timespec imageWriteTime;
    int preampGain;
    int analogGain;
    float sunCenter[2];
    float sunCenterError[2];
    int imageMinMax[2];
    float XYinterceptslope[4];
    double CTLsolution[2];
    float screenCenter[2];
    float screenCenterError[2];
    int fiducialCount;
    float fiducialX[10];
    float fiducialY[10];
    int limbCount;
    float limbX[10];
    float limbY[10];
    //float limbXerror[10];
    //float limbYerror[10];
    int fiducialIDX[10];
    int fiducialIDY[10];
    float cpuVoltage[5];
    bool isTracking;
    bool isOutputting;

    float latitude;
    float longitude;
    float solarTarget[2];
    double northAngle;
    float clockingAngle;
};

int writePNGImage(cv::InputArray _image, const std::string fileName);
int writeFITSImage(cv::InputArray, HeaderData keys, const std::string fileName);
int readFITSImage(const std::string fileName, cv::OutputArray image);
int readFITSHeader(const std::string fileName, HeaderData &keys);
<|endoftext|>