<commit_before>// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s

namespace fizbin { class Foobar; } // expected-note{{'fizbin::Foobar' declared here}}
Foobar *my_bar = new Foobar; // expected-error{{unknown type name 'Foobar'; did you mean 'fizbin::Foobar'?}} \
                             // expected-error{{expected a type}}

namespace barstool { int toFoobar() { return 1; } } // expected-note 3 {{'barstool::toFoobar' declared here}}
int Double(int x) { return x + x; }
void empty() {
  Double(toFoobar()); // expected-error{{{use of undeclared identifier 'toFoobar'; did you mean 'barstool::toFoobar'?}}
}

namespace fizbin {
  namespace baztool { bool toFoobar() { return true; } } // expected-note{{'fizbin::baztool' declared here}}
  namespace nested { bool moreFoobar() { return true; } } // expected-note{{'fizbin::nested::moreFoobar' declared here}}
  namespace nested { bool lessFoobar() { return true; } } // expected-note{{'fizbin::nested' declared here}} \
                                                          // expected-note{{'fizbin::nested::lessFoobar' declared here}}
  class dummy { // expected-note 2 {{'fizbin::dummy' declared here}}
   public:
    static bool moreFoobar() { return false; } // expected-note{{'moreFoobar' declared here}}
  };
}
void Check() { // expected-note{{'Check' declared here}}
  if (toFoobar()) Double(7); // expected-error{{use of undeclared identifier 'toFoobar'; did you mean 'barstool::toFoobar'?}}
  if (noFoobar()) Double(7); // expected-error{{use of undeclared identifier 'noFoobar'; did you mean 'barstool::toFoobar'?}}
  if (moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'moreFoobar'; did you mean 'fizbin::nested::moreFoobar'}}
  if (lessFoobar()) Double(7); // expected-error{{use of undeclared identifier 'lessFoobar'; did you mean 'fizbin::nested::lessFoobar'?}}
  if (baztool::toFoobar()) Double(7); // expected-error{{use of undeclared identifier 'baztool'; did you mean 'fizbin::baztool'?}}
  if (nested::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'nested'; did you mean 'fizbin::nested'?}}
  if (dummy::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}}
  if (dummy::mreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}} \
                                     // expected-error{{no member named 'mreFoobar' in 'fizbin::dummy'; did you mean 'moreFoobar'?}}
  if (moFoobin()) Double(7); // expected-error{{use of undeclared identifier 'moFoobin'}}
}

void Alt() {
  Cleck(); // expected-error{{{use of undeclared identifier 'Cleck'; did you mean 'Check'?}}
}

namespace N {
  namespace inner {
    class myvector { /* ... */ }; // expected-note{{'inner::myvector' declared here}}
  }

  void f() {
    myvector v; // expected-error{{unknown type name 'myvector'; did you mean 'inner::myvector'?}}
  }
}

namespace realstd {
  inline namespace __1 {
    class mylinkedlist { /* ... */ }; // expected-note 2 {{'realstd::mylinkedlist' declared here}}
  }

  class linkedlist { /* ... */ };
}

void f() {
  mylinkedlist v; // expected-error{{unknown type name 'mylinkedlist'; did you mean 'realstd::mylinkedlist'?}}
  nylinkedlist w; // expected-error{{unknown type name 'nylinkedlist'; did you mean 'realstd::mylinkedlist'?}}
}

// Test case from http://llvm.org/bugs/show_bug.cgi?id=10318
namespace llvm {
 template <typename T> class GraphWriter {}; // expected-note{{'llvm::GraphWriter' declared here}}
}

struct S {};
void bar() {
 GraphWriter<S> x; //expected-error{{no template named 'GraphWriter'; did you mean 'llvm::GraphWriter'?}}

}
<commit_msg>Split the two invalid uses of the unqualified Foobar at line 3 to two lines so that it is clearer which use triggered which error.<commit_after>// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s

namespace fizbin { class Foobar; } // expected-note{{'fizbin::Foobar' declared here}}
Foobar *my_bar  // expected-error{{unknown type name 'Foobar'; did you mean 'fizbin::Foobar'?}}
    = new Foobar;  // expected-error{{expected a type}}

namespace barstool { int toFoobar() { return 1; } } // expected-note 3 {{'barstool::toFoobar' declared here}}
int Double(int x) { return x + x; }
void empty() {
  Double(toFoobar()); // expected-error{{{use of undeclared identifier 'toFoobar'; did you mean 'barstool::toFoobar'?}}
}

namespace fizbin {
  namespace baztool { bool toFoobar() { return true; } } // expected-note{{'fizbin::baztool' declared here}}
  namespace nested { bool moreFoobar() { return true; } } // expected-note{{'fizbin::nested::moreFoobar' declared here}}
  namespace nested { bool lessFoobar() { return true; } } // expected-note{{'fizbin::nested' declared here}} \
                                                          // expected-note{{'fizbin::nested::lessFoobar' declared here}}
  class dummy { // expected-note 2 {{'fizbin::dummy' declared here}}
   public:
    static bool moreFoobar() { return false; } // expected-note{{'moreFoobar' declared here}}
  };
}
void Check() { // expected-note{{'Check' declared here}}
  if (toFoobar()) Double(7); // expected-error{{use of undeclared identifier 'toFoobar'; did you mean 'barstool::toFoobar'?}}
  if (noFoobar()) Double(7); // expected-error{{use of undeclared identifier 'noFoobar'; did you mean 'barstool::toFoobar'?}}
  if (moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'moreFoobar'; did you mean 'fizbin::nested::moreFoobar'}}
  if (lessFoobar()) Double(7); // expected-error{{use of undeclared identifier 'lessFoobar'; did you mean 'fizbin::nested::lessFoobar'?}}
  if (baztool::toFoobar()) Double(7); // expected-error{{use of undeclared identifier 'baztool'; did you mean 'fizbin::baztool'?}}
  if (nested::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'nested'; did you mean 'fizbin::nested'?}}
  if (dummy::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}}
  if (dummy::mreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}} \
                                     // expected-error{{no member named 'mreFoobar' in 'fizbin::dummy'; did you mean 'moreFoobar'?}}
  if (moFoobin()) Double(7); // expected-error{{use of undeclared identifier 'moFoobin'}}
}

void Alt() {
  Cleck(); // expected-error{{{use of undeclared identifier 'Cleck'; did you mean 'Check'?}}
}

namespace N {
  namespace inner {
    class myvector { /* ... */ }; // expected-note{{'inner::myvector' declared here}}
  }

  void f() {
    myvector v; // expected-error{{unknown type name 'myvector'; did you mean 'inner::myvector'?}}
  }
}

namespace realstd {
  inline namespace __1 {
    class mylinkedlist { /* ... */ }; // expected-note 2 {{'realstd::mylinkedlist' declared here}}
  }

  class linkedlist { /* ... */ };
}

void f() {
  mylinkedlist v; // expected-error{{unknown type name 'mylinkedlist'; did you mean 'realstd::mylinkedlist'?}}
  nylinkedlist w; // expected-error{{unknown type name 'nylinkedlist'; did you mean 'realstd::mylinkedlist'?}}
}

// Test case from http://llvm.org/bugs/show_bug.cgi?id=10318
namespace llvm {
 template <typename T> class GraphWriter {}; // expected-note{{'llvm::GraphWriter' declared here}}
}

struct S {};
void bar() {
 GraphWriter<S> x; //expected-error{{no template named 'GraphWriter'; did you mean 'llvm::GraphWriter'?}}

}
<|endoftext|>


<commit_before>/*
    KNode, the KDE newsreader
    Copyright (c) 1999-2005 the KNode authors.
    See file AUTHORS for details

    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.
    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, US
*/

#include <kdebug.h>
#include <klocale.h>
#include <kio/job.h>

#include <libkdepim/progressmanager.h>

#include "knarticle.h"
#include "knglobals.h"
#include "knnntpaccount.h"
#include "scheduler.h"

//Added by qt3to4:
#include <QTimer>

KNJobConsumer::KNJobConsumer()
{
}

KNJobConsumer::~KNJobConsumer()
{
  for ( QList<KNJobData*>::Iterator it = mJobs.begin(); it != mJobs.end(); ++it )
    (*it)->c_onsumer = 0;
}

void KNJobConsumer::emitJob( KNJobData *j )
{
  if ( j ) {
    mJobs.append( j );
    knGlobals.scheduler()->addJob( j );
  }
}

void KNJobConsumer::jobDone( KNJobData *j )
{
  if ( j && mJobs.removeAll( j ) )
    processJob( j );
}

void KNJobConsumer::processJob( KNJobData *j )
{
  delete j;
}

// the assingment of a_ccount may cause race conditions, check again.... (CG)
KNJobData::KNJobData(jobType t, KNJobConsumer *c, KNServerInfo *a, KNJobItem *i) :
  t_ype(t), d_ata(i), a_ccount(a),
  mError( 0 ),
  mCanceled( false ),
  c_onsumer( c ),
  mJob( 0 ),
  mProgressItem( 0 )
{
  d_ata->setLocked(true);
}

KNJobData::~KNJobData()
{
  d_ata->setLocked(false);
}

void KNJobData::notifyConsumer()
{

  if(c_onsumer)
    c_onsumer->jobDone(this);
  else
    delete this;
}

void KNJobData::cancel()
{
  mCanceled = true;
  if ( mJob ) {
    mJob->kill();
    mJob = 0;
  }
  if ( mProgressItem ) {
    mProgressItem->setStatus( "Canceled" );
    mProgressItem->setComplete();
    mProgressItem = 0;
  }
  emitFinished();
}

void KNJobData::emitFinished()
{
  QTimer::singleShot( 0, this, SLOT(slotEmitFinished()) );
}

void KNJobData::setupKJob(KJob * job)
{
  mJob = job;
  if ( job ) {
    connect( job, SIGNAL( percent(KJob*, unsigned long) ),
             SLOT( slotJobPercent(KJob*, unsigned long) ) );
    connect( job, SIGNAL( infoMessage(KJob*, const QString&) ),
             SLOT( slotJobInfoMessage(KJob*, const QString&) ) );
  }
}

void KNJobData::setupKIOJob( KIO::Job *job )
{
  if ( job ) {
    if ( account() ) {
      if ( account()->encryption() == KNServerInfo::TLS )
        job->addMetaData( "tls", "on" );
      else
        job->addMetaData( "tls", "off" );
    }
  }
  setupKJob( job );
}

void KNJobData::createProgressItem()
{
  if ( mProgressItem )
    return;
  KNNntpAccount *acc = static_cast<KNNntpAccount*>( account() );
  QString msg = i18n( "KNode" );
  if ( type() == JTmail )
    msg = i18n( "Sending message" );
  else {
    if ( acc )
      msg = acc->name();
  }
  bool encr = false;
  if ( acc && acc->encryption() != KNServerInfo::None )
    encr = true;
  mProgressItem = KPIM::ProgressManager::createProgressItem( 0,
      KPIM::ProgressManager::getUniqueID(), msg, i18n( "Waiting..." ), true, encr );
}

void KNJobData::slotJobPercent( KJob*, unsigned long percent )
{
  kDebug(5003) <<"Progress:" << percent;
  setProgress( percent );
}

void KNJobData::slotJobInfoMessage( KJob*, const QString &msg )
{
  kDebug(5003) <<"Status:" << msg;
  setStatus( msg );
}

void KNJobData::slotEmitFinished( )
{
  emit finished( this );
}

KUrl KNJobData::baseUrl() const
{
  KUrl url;
  if ( account()->encryption() == KNServerInfo::SSL )
    url.setProtocol( "nntps" );
  else
    url.setProtocol( "nntp" );
  url.setHost( account()->server() );
  url.setPort( account()->port() );
  if ( account()->needsLogon() ) {
    url.setUser( account()->user() );
    url.setPass( account()->pass() );
  }
  return url;
}

void KNJobData::setError( int err, const QString & errMsg )
{
  mError = err;
  mErrorString = errMsg;
}

#include "knjobdata.moc"
<commit_msg>Backport of r945671.<commit_after>/*
    KNode, the KDE newsreader
    Copyright (c) 1999-2005 the KNode authors.
    See file AUTHORS for details

    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.
    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, US
*/

#include <kdebug.h>
#include <klocale.h>
#include <kio/job.h>

#include <libkdepim/progressmanager.h>

#include "knarticle.h"
#include "knglobals.h"
#include "knnntpaccount.h"
#include "scheduler.h"

//Added by qt3to4:
#include <QTimer>

KNJobConsumer::KNJobConsumer()
{
}

KNJobConsumer::~KNJobConsumer()
{
  for ( QList<KNJobData*>::Iterator it = mJobs.begin(); it != mJobs.end(); ++it )
    (*it)->c_onsumer = 0;
}

void KNJobConsumer::emitJob( KNJobData *j )
{
  if ( j ) {
    mJobs.append( j );
    knGlobals.scheduler()->addJob( j );
  }
}

void KNJobConsumer::jobDone( KNJobData *j )
{
  if ( j && mJobs.removeAll( j ) )
    processJob( j );
}

void KNJobConsumer::processJob( KNJobData *j )
{
  delete j;
}

// the assingment of a_ccount may cause race conditions, check again.... (CG)
KNJobData::KNJobData(jobType t, KNJobConsumer *c, KNServerInfo *a, KNJobItem *i) :
  t_ype(t), d_ata(i), a_ccount(a),
  mError( 0 ),
  mCanceled( false ),
  c_onsumer( c ),
  mJob( 0 ),
  mProgressItem( 0 )
{
  d_ata->setLocked(true);
}

KNJobData::~KNJobData()
{
  d_ata->setLocked(false);
}

void KNJobData::notifyConsumer()
{

  if(c_onsumer)
    c_onsumer->jobDone(this);
  else
    delete this;
}

void KNJobData::cancel()
{
  mCanceled = true;
  if ( mJob ) {
    mJob->kill();
    mJob = 0;
  }
  if ( mProgressItem ) {
    mProgressItem->setStatus( "Canceled" );
    mProgressItem->setComplete();
    mProgressItem = 0;
  }
  emitFinished();
}

void KNJobData::emitFinished()
{
  QTimer::singleShot( 0, this, SLOT(slotEmitFinished()) );
}

void KNJobData::setupKJob(KJob * job)
{
  mJob = job;
  if ( job ) {
    connect( job, SIGNAL( percent(KJob*, unsigned long) ),
             SLOT( slotJobPercent(KJob*, unsigned long) ) );
    connect( job, SIGNAL( infoMessage(KJob*, const QString&) ),
             SLOT( slotJobInfoMessage(KJob*, const QString&) ) );
  }
}

void KNJobData::setupKIOJob( KIO::Job *job )
{
  if ( job ) {
    if ( account() ) {
      if ( account()->encryption() == KNServerInfo::TLS )
        job->addMetaData( "tls", "on" );
      else
        job->addMetaData( "tls", "off" );
    }
  }
  job->setUiDelegate(0);
  setupKJob( job );
}

void KNJobData::createProgressItem()
{
  if ( mProgressItem )
    return;
  KNNntpAccount *acc = static_cast<KNNntpAccount*>( account() );
  QString msg = i18n( "KNode" );
  if ( type() == JTmail )
    msg = i18n( "Sending message" );
  else {
    if ( acc )
      msg = acc->name();
  }
  bool encr = false;
  if ( acc && acc->encryption() != KNServerInfo::None )
    encr = true;
  mProgressItem = KPIM::ProgressManager::createProgressItem( 0,
      KPIM::ProgressManager::getUniqueID(), msg, i18n( "Waiting..." ), true, encr );
}

void KNJobData::slotJobPercent( KJob*, unsigned long percent )
{
  kDebug(5003) <<"Progress:" << percent;
  setProgress( percent );
}

void KNJobData::slotJobInfoMessage( KJob*, const QString &msg )
{
  kDebug(5003) <<"Status:" << msg;
  setStatus( msg );
}

void KNJobData::slotEmitFinished( )
{
  emit finished( this );
}

KUrl KNJobData::baseUrl() const
{
  KUrl url;
  if ( account()->encryption() == KNServerInfo::SSL )
    url.setProtocol( "nntps" );
  else
    url.setProtocol( "nntp" );
  url.setHost( account()->server() );
  url.setPort( account()->port() );
  if ( account()->needsLogon() ) {
    url.setUser( account()->user() );
    url.setPass( account()->pass() );
  }
  return url;
}

void KNJobData::setError( int err, const QString & errMsg )
{
  mError = err;
  mErrorString = errMsg;
}

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


<commit_before>/*

Copyright (c) 2006-2015, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef ROUTING_TABLE_HPP
#define ROUTING_TABLE_HPP

#include "libtorrent/aux_/disable_warnings_push.hpp"

#include <vector>
#include <set>

#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/array.hpp>
#include <boost/noncopyable.hpp>
#include <boost/unordered_set.hpp>

#include "libtorrent/aux_/disable_warnings_pop.hpp"

#include <libtorrent/kademlia/node_id.hpp>
#include <libtorrent/kademlia/node_entry.hpp>
#include <libtorrent/session_settings.hpp>
#include <libtorrent/assert.hpp>
#include <libtorrent/time.hpp>

namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
	struct session_status;
#endif
	struct dht_routing_bucket;
}

namespace libtorrent { namespace dht
{
struct dht_logger;

typedef std::vector<node_entry> bucket_t;

struct routing_table_node
{
	bucket_t replacements;
	bucket_t live_nodes;
};

// differences in the implementation from the description in
// the paper:
//
// * Nodes are not marked as being stale, they keep a counter
// 	that tells how many times in a row they have failed. When
// 	a new node is to be inserted, the node that has failed
// 	the most times is replaced. If none of the nodes in the
// 	bucket has failed, then it is put in the replacement
// 	cache (just like in the paper).

class TORRENT_EXTRA_EXPORT routing_table : boost::noncopyable
{
public:
	typedef std::vector<routing_table_node> table_t;

	routing_table(node_id const& id, int bucket_size
		, dht_settings const& settings
		, dht_logger* log);

#ifndef TORRENT_NO_DEPRECATE
	void status(session_status& s) const;
#endif

	void status(std::vector<dht_routing_bucket>& s) const;

	void node_failed(node_id const& id, udp::endpoint const& ep);

	// adds an endpoint that will never be added to
	// the routing table
	void add_router_node(udp::endpoint router);

	// iterates over the router nodes added
	typedef std::set<udp::endpoint>::const_iterator router_iterator;
	router_iterator router_begin() const { return m_router_nodes.begin(); }
	router_iterator router_end() const { return m_router_nodes.end(); }

	enum add_node_status_t {
		failed_to_add = 0,
		node_added,
		need_bucket_split
	};
	add_node_status_t add_node_impl(node_entry e);

	bool add_node(node_entry e);

	// this function is called every time the node sees
	// a sign of a node being alive. This node will either
	// be inserted in the k-buckets or be moved to the top
	// of its bucket.
	bool node_seen(node_id const& id, udp::endpoint ep, int rtt);

	// this may add a node to the routing table and mark it as
	// not pinged. If the bucket the node falls into is full,
	// the node will be ignored.
	void heard_about(node_id const& id, udp::endpoint const& ep);

	node_entry const* next_refresh();

	enum
	{
		// nodes that have not been pinged are considered failed by this flag
		include_failed = 1
	};

	// fills the vector with the count nodes from our buckets that
	// are nearest to the given id.
	void find_node(node_id const& id, std::vector<node_entry>& l
		, int options, int count = 0);
	void remove_node(node_entry* n
		, table_t::iterator bucket) ;

	int bucket_size(int bucket) const
	{
		int num_buckets = m_buckets.size();
		if (num_buckets == 0) return 0;
		if (bucket < num_buckets) bucket = num_buckets - 1;
		table_t::const_iterator i = m_buckets.begin();
		std::advance(i, bucket);
		return int(i->live_nodes.size());
	}

	void for_each_node(void (*)(void*, node_entry const&)
		, void (*)(void*, node_entry const&), void* userdata) const;

	int bucket_size() const { return m_bucket_size; }

	// returns the number of nodes in the main buckets, number of nodes in the
	// replacement buckets and the number of nodes in the main buckets that have
	// been pinged and confirmed up
	boost::tuple<int, int, int> size() const;

	boost::int64_t num_global_nodes() const;

	// the number of bits down we have full buckets
	// i.e. essentially the number of full buckets
	// we have
	int depth() const;

	int num_active_buckets() const { return m_buckets.size(); }

	void replacement_cache(bucket_t& nodes) const;

#if defined TORRENT_DEBUG
	// used for debug and monitoring purposes. This will print out
	// the state of the routing table to the given stream
	void print_state(std::ostream& os) const;
#endif

	int bucket_limit(int bucket) const;

#if TORRENT_USE_INVARIANT_CHECKS
	void check_invariant() const;
#endif

private:

	dht_logger* m_log;

	table_t::iterator find_bucket(node_id const& id);

	void split_bucket();

	// return a pointer the node_entry with the given endpoint
	// or 0 if we don't have such a node. Both the address and the
	// port has to match
	node_entry* find_node(udp::endpoint const& ep
		, routing_table::table_t::iterator* bucket);

	dht_settings const& m_settings;

	// (k-bucket, replacement cache) pairs
	// the first entry is the bucket the furthest
	// away from our own ID. Each time the bucket
	// closest to us (m_buckets.back()) has more than
	// bucket size nodes in it, another bucket is
	// added to the end and it's split up between them
	table_t m_buckets;

	node_id m_id; // our own node id

	// the last seen depth (i.e. levels in the routing table)
	// it's mutable because it's updated by depth(), which is const
	mutable int m_depth;

	// the last time we refreshed our own bucket
	// refreshed every 15 minutes
	mutable time_point m_last_self_refresh;

	// this is a set of all the endpoints that have
	// been identified as router nodes. They will
	// be used in searches, but they will never
	// be added to the routing table.
	std::set<udp::endpoint> m_router_nodes;

	// these are all the IPs that are in the routing
	// table. It's used to only allow a single entry
	// per IP in the whole table. Currently only for
	// IPv4
	boost::unordered_multiset<address_v4::bytes_type> m_ips;

	// constant called k in paper
	int m_bucket_size;
};

} } // namespace libtorrent::dht

#endif // ROUTING_TABLE_HPP

<commit_msg>Fix routing_table bucket_size(int bucket) out_of_range logic error.<commit_after>/*

Copyright (c) 2006-2015, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef ROUTING_TABLE_HPP
#define ROUTING_TABLE_HPP

#include "libtorrent/aux_/disable_warnings_push.hpp"

#include <vector>
#include <set>

#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/array.hpp>
#include <boost/noncopyable.hpp>
#include <boost/unordered_set.hpp>

#include "libtorrent/aux_/disable_warnings_pop.hpp"

#include <libtorrent/kademlia/node_id.hpp>
#include <libtorrent/kademlia/node_entry.hpp>
#include <libtorrent/session_settings.hpp>
#include <libtorrent/assert.hpp>
#include <libtorrent/time.hpp>

namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
	struct session_status;
#endif
	struct dht_routing_bucket;
}

namespace libtorrent { namespace dht
{
struct dht_logger;

typedef std::vector<node_entry> bucket_t;

struct routing_table_node
{
	bucket_t replacements;
	bucket_t live_nodes;
};

// differences in the implementation from the description in
// the paper:
//
// * Nodes are not marked as being stale, they keep a counter
// 	that tells how many times in a row they have failed. When
// 	a new node is to be inserted, the node that has failed
// 	the most times is replaced. If none of the nodes in the
// 	bucket has failed, then it is put in the replacement
// 	cache (just like in the paper).

class TORRENT_EXTRA_EXPORT routing_table : boost::noncopyable
{
public:
	typedef std::vector<routing_table_node> table_t;

	routing_table(node_id const& id, int bucket_size
		, dht_settings const& settings
		, dht_logger* log);

#ifndef TORRENT_NO_DEPRECATE
	void status(session_status& s) const;
#endif

	void status(std::vector<dht_routing_bucket>& s) const;

	void node_failed(node_id const& id, udp::endpoint const& ep);

	// adds an endpoint that will never be added to
	// the routing table
	void add_router_node(udp::endpoint router);

	// iterates over the router nodes added
	typedef std::set<udp::endpoint>::const_iterator router_iterator;
	router_iterator router_begin() const { return m_router_nodes.begin(); }
	router_iterator router_end() const { return m_router_nodes.end(); }

	enum add_node_status_t {
		failed_to_add = 0,
		node_added,
		need_bucket_split
	};
	add_node_status_t add_node_impl(node_entry e);

	bool add_node(node_entry e);

	// this function is called every time the node sees
	// a sign of a node being alive. This node will either
	// be inserted in the k-buckets or be moved to the top
	// of its bucket.
	bool node_seen(node_id const& id, udp::endpoint ep, int rtt);

	// this may add a node to the routing table and mark it as
	// not pinged. If the bucket the node falls into is full,
	// the node will be ignored.
	void heard_about(node_id const& id, udp::endpoint const& ep);

	node_entry const* next_refresh();

	enum
	{
		// nodes that have not been pinged are considered failed by this flag
		include_failed = 1
	};

	// fills the vector with the count nodes from our buckets that
	// are nearest to the given id.
	void find_node(node_id const& id, std::vector<node_entry>& l
		, int options, int count = 0);
	void remove_node(node_entry* n
		, table_t::iterator bucket) ;

	int bucket_size(int bucket) const
	{
		int num_buckets = m_buckets.size();
		if (num_buckets == 0) return 0;
		if (bucket >= num_buckets) bucket = num_buckets - 1;
		table_t::const_iterator i = m_buckets.begin();
		std::advance(i, bucket);
		return int(i->live_nodes.size());
	}

	void for_each_node(void (*)(void*, node_entry const&)
		, void (*)(void*, node_entry const&), void* userdata) const;

	int bucket_size() const { return m_bucket_size; }

	// returns the number of nodes in the main buckets, number of nodes in the
	// replacement buckets and the number of nodes in the main buckets that have
	// been pinged and confirmed up
	boost::tuple<int, int, int> size() const;

	boost::int64_t num_global_nodes() const;

	// the number of bits down we have full buckets
	// i.e. essentially the number of full buckets
	// we have
	int depth() const;

	int num_active_buckets() const { return m_buckets.size(); }

	void replacement_cache(bucket_t& nodes) const;

#if defined TORRENT_DEBUG
	// used for debug and monitoring purposes. This will print out
	// the state of the routing table to the given stream
	void print_state(std::ostream& os) const;
#endif

	int bucket_limit(int bucket) const;

#if TORRENT_USE_INVARIANT_CHECKS
	void check_invariant() const;
#endif

private:

	dht_logger* m_log;

	table_t::iterator find_bucket(node_id const& id);

	void split_bucket();

	// return a pointer the node_entry with the given endpoint
	// or 0 if we don't have such a node. Both the address and the
	// port has to match
	node_entry* find_node(udp::endpoint const& ep
		, routing_table::table_t::iterator* bucket);

	dht_settings const& m_settings;

	// (k-bucket, replacement cache) pairs
	// the first entry is the bucket the furthest
	// away from our own ID. Each time the bucket
	// closest to us (m_buckets.back()) has more than
	// bucket size nodes in it, another bucket is
	// added to the end and it's split up between them
	table_t m_buckets;

	node_id m_id; // our own node id

	// the last seen depth (i.e. levels in the routing table)
	// it's mutable because it's updated by depth(), which is const
	mutable int m_depth;

	// the last time we refreshed our own bucket
	// refreshed every 15 minutes
	mutable time_point m_last_self_refresh;

	// this is a set of all the endpoints that have
	// been identified as router nodes. They will
	// be used in searches, but they will never
	// be added to the routing table.
	std::set<udp::endpoint> m_router_nodes;

	// these are all the IPs that are in the routing
	// table. It's used to only allow a single entry
	// per IP in the whole table. Currently only for
	// IPv4
	boost::unordered_multiset<address_v4::bytes_type> m_ips;

	// constant called k in paper
	int m_bucket_size;
};

} } // namespace libtorrent::dht

#endif // ROUTING_TABLE_HPP

<|endoftext|>


<commit_before>/*
  BelaCsound.cpp:

  Copyright (C) 2017 V Lazzarini

  This file is part of Csound.

  The Csound 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 of the License, or (at your option) any later version.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/

#include <getopt.h>
#include <Bela.h>
#include <Midi.h>
#include <csound.hpp>
#include <plugin.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <atomic>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);
static int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiOutDevice(CSOUND *csound, void *userData);
static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf,
			 int nbytes);

/** DigiIn opcode
    ksig digiInBela ipin
    asig digiInBela ipin
*/
struct DigiIn : csnd::Plugin<1, 1> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[0];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    fcount = 0;
    init_done = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
   if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    outargs[0] = (MYFLT) digitalRead(context,fcount,pin);
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig out(this, outargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    for (auto &s : out) {
      s = (MYFLT) digitalRead(context,cnt,pin);
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

/** DigiOut opcode
    digiOutBela ksig,ipin
    digiOutBela asig,ipin
*/
struct DigiOut : csnd::Plugin<0, 2> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[1];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    init_done = 0;
    fcount = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    digitalWrite(context,fcount,pin,(inargs[0] > 0.0 ? 1 : 0));
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig in(this, inargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    for (auto s : in) {
      digitalWriteOnce(context,cnt,pin, (s > 0.0 ? 1 : 0));
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

struct CsChan {
  std::vector<MYFLT> samples;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  std::string csdfile;
  int blocksize;
  std::atomic_int res;
  int count;
  CsChan channel[ANCHNS];
  CsChan ochannel[ANCHNS];
};

bool csound_setup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  Csound *csound;
  const char *args[] = { "csound", csData->csdfile.c_str(), "-iadc",
			 "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon" };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Error: number of audio inputs != number of audio outputs.\n");
    return false;
  }

  if(context->analogInChannels != context->analogOutChannels) {
    printf("Error: number of analog inputs != number of analog outputs.\n");
    return false;
  }

  /* set up Csound */
  csound = new Csound();
  csData->csound = csound;
  csound->SetHostData((void *) context);
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  csound->SetExternalMidiOutOpenCallback(OpenMidiOutDevice);
  csound->SetExternalMidiWriteCallback(WriteMidiData);
  csound->SetExternalMidiOutCloseCallback(CloseMidiOutDevice);
  /* set up digi opcodes */
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "k","i", csnd::thread::ik) != 0)
    printf("Warning: could not add digiInBela k-rate opcode\n");
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "a", "i", csnd::thread::ia) != 0)
    printf("Warning: could not add digiInBela a-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ki", csnd::thread::ik) != 0)
    printf("Warning: could not add digiOutBela k-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ai", csnd::thread::ia) != 0)
    printf("Warning: could not add digiOutBela a-rate opcode\n");

  /* compile CSD */
  if((csData->res = csound->Compile(numArgs, args)) != 0) {
    printf("Error: Csound could not compile CSD file.\n");
    return false;
  }
  csData->blocksize = csound->GetKsmps()*csound->GetNchnls();
  csData->count = 0;

  /* set up the channels */
  for(int i=0; i < ANCHNS; i++) {
    csData->channel[i].samples.resize(csound->GetKsmps());
    csData->channel[i].name << "analogIn" << i;
    csData->ochannel[i].samples.resize(csound->GetKsmps());
    csData->ochannel[i].name << "analogOut" << i;
  }

  return true;
}

void csound_render(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  if(csData->res == 0) {
    int i,k,count, frmcount,blocksize,res = csData->res;
    unsigned int n;
    Csound *csound = csData->csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = (unsigned int) nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = csData->channel;
    CsChan *ochannel = csData->ochannel;
    float frm = 0.f, incr =
      ((float) context->analogFrames)/context->audioFrames;
    count = csData->count;
    blocksize = csData->blocksize;

    /* processing loop */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {

	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     channel[i].samples.data());
	  csound->GetAudioChannel(ochannel[i].name.str().c_str(),
				  ochannel[i].samples.data());
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else break;

      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }
      /* read analogue data
         analogue frame pos frm gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].samples[frmcount] = analogRead(context,k,i);
	analogWriteOnce(context,k,i,ochannel[i].samples[frmcount]);
      }
    }
    csData->res = res;
    csData->count = count;
  }
}

void csound_cleanup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  delete csData->csound;
}

Midi gMidi;

/** MIDI functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = &gMidi
  if(midi->readFrom(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi in device %s", dev);
  return -1;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  return 0;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0, byte;
  if(userData) {
    Midi *midi = (Midi *) userData;
    while((byte = midi->getInput()) >= 0) {
      *mbuf++ = (unsigned char) byte;
      if(++n == nbytes) break;
    }
    return n;
  }
  return 0;
}

int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = &gMidi;
  if(midi->writeTo(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi out device %s", dev);
  return -1;
}

int CloseMidiOutDevice(CSOUND *csound, void *userData) {
  return 0;
}

int WriteMidiData(CSOUND *csound, void *userData,
		  const unsigned char *mbuf, int nbytes) {
  if(userData) {
    Midi *midi = (Midi *) userData;
    if(midi->writeOutput((midi_byte_t *)mbuf, nbytes) > 0) return nbytes;
    return 0;
  }
  return 0;
}

void usage(const char *prg) {
  std::cerr << prg << " [options]\n";
  Bela_usage();
  std::cerr << "  --csd=name [-f name]: CSD file name\n";
  std::cerr << "  --help [-h]: help message\n";
}

/**
   Main program: takes Bela options and a --csd=<csdfile>
   option for Csound
*/
int main(int argc, const char *argv[]) {
  CsData csData;
  int c;
  bool res = false;
  BelaInitSettings settings;
  const option opt[] = {{"csd", required_argument, NULL, 'f'},
			{"help", 0, NULL, 'h'},
			{NULL, 0, NULL, 0}};

  Bela_defaultSettings(&settings);
  settings.setup = csound_setup;
  settings.render = csound_render;
  settings.cleanup = csound_cleanup;
  settings.highPerformanceMode = 1;
  settings.interleave = 1;
  settings.analogOutputsPersist = 0;

  while((c = Bela_getopt_long(argc, (char **) argv, "hf", opt, &settings)) >= 0) {
    if (c == 'h') {
      usage(argv[0]);
      return 1;
    } else if (c == 'f') {
      csData.csdfile = optarg;
      res = true;
    } else {
      usage(argv[0]);
      return 1;
    }
  }

  if(res) {
    res = Bela_initAudio(&settings, &csData);
    if(!res){
      if(Bela_startAudio() == 0) {
         while(csData.res == 0)
	   usleep(100000);
      } else
	std::cerr << "error starting audio \n";
      Bela_stopAudio();
    } else
      std::cerr << "error initialising Bela \n";
    Bela_cleanupAudio();
    return 0;
  }
  std::cerr << "no csd provided, use --csd=name \n";
  return 1;
}
<commit_msg>Bela main program MIDI fix<commit_after>/*
  BelaCsound.cpp:

  Copyright (C) 2017 V Lazzarini

  This file is part of Csound.

  The Csound 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 of the License, or (at your option) any later version.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/

#include <getopt.h>
#include <Bela.h>
#include <Midi.h>
#include <csound.hpp>
#include <plugin.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <atomic>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);
static int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiOutDevice(CSOUND *csound, void *userData);
static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf,
			 int nbytes);

/** DigiIn opcode
    ksig digiInBela ipin
    asig digiInBela ipin
*/
struct DigiIn : csnd::Plugin<1, 1> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[0];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    fcount = 0;
    init_done = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
   if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    outargs[0] = (MYFLT) digitalRead(context,fcount,pin);
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig out(this, outargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    for (auto &s : out) {
      s = (MYFLT) digitalRead(context,cnt,pin);
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

/** DigiOut opcode
    digiOutBela ksig,ipin
    digiOutBela asig,ipin
*/
struct DigiOut : csnd::Plugin<0, 2> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[1];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    init_done = 0;
    fcount = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    digitalWrite(context,fcount,pin,(inargs[0] > 0.0 ? 1 : 0));
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig in(this, inargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    for (auto s : in) {
      digitalWriteOnce(context,cnt,pin, (s > 0.0 ? 1 : 0));
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

struct CsChan {
  std::vector<MYFLT> samples;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  std::string csdfile;
  int blocksize;
  std::atomic_int res;
  int count;
  CsChan channel[ANCHNS];
  CsChan ochannel[ANCHNS];
};

bool csound_setup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  Csound *csound;
  const char *args[] = { "csound", csData->csdfile.c_str(), "-iadc",
			 "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon" };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Error: number of audio inputs != number of audio outputs.\n");
    return false;
  }

  if(context->analogInChannels != context->analogOutChannels) {
    printf("Error: number of analog inputs != number of analog outputs.\n");
    return false;
  }

  /* set up Csound */
  csound = new Csound();
  csData->csound = csound;
  csound->SetHostData((void *) context);
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  csound->SetExternalMidiOutOpenCallback(OpenMidiOutDevice);
  csound->SetExternalMidiWriteCallback(WriteMidiData);
  csound->SetExternalMidiOutCloseCallback(CloseMidiOutDevice);
  /* set up digi opcodes */
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "k","i", csnd::thread::ik) != 0)
    printf("Warning: could not add digiInBela k-rate opcode\n");
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "a", "i", csnd::thread::ia) != 0)
    printf("Warning: could not add digiInBela a-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ki", csnd::thread::ik) != 0)
    printf("Warning: could not add digiOutBela k-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ai", csnd::thread::ia) != 0)
    printf("Warning: could not add digiOutBela a-rate opcode\n");

  /* compile CSD */
  if((csData->res = csound->Compile(numArgs, args)) != 0) {
    printf("Error: Csound could not compile CSD file.\n");
    return false;
  }
  csData->blocksize = csound->GetKsmps()*csound->GetNchnls();
  csData->count = 0;

  /* set up the channels */
  for(int i=0; i < ANCHNS; i++) {
    csData->channel[i].samples.resize(csound->GetKsmps());
    csData->channel[i].name << "analogIn" << i;
    csData->ochannel[i].samples.resize(csound->GetKsmps());
    csData->ochannel[i].name << "analogOut" << i;
  }

  return true;
}

void csound_render(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  if(csData->res == 0) {
    int i,k,count, frmcount,blocksize,res = csData->res;
    unsigned int n;
    Csound *csound = csData->csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = (unsigned int) nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = csData->channel;
    CsChan *ochannel = csData->ochannel;
    float frm = 0.f, incr =
      ((float) context->analogFrames)/context->audioFrames;
    count = csData->count;
    blocksize = csData->blocksize;

    /* processing loop */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {

	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     channel[i].samples.data());
	  csound->GetAudioChannel(ochannel[i].name.str().c_str(),
				  ochannel[i].samples.data());
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else break;

      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }
      /* read analogue data
         analogue frame pos frm gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].samples[frmcount] = analogRead(context,k,i);
	analogWriteOnce(context,k,i,ochannel[i].samples[frmcount]);
      }
    }
    csData->res = res;
    csData->count = count;
  }
}

void csound_cleanup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  delete csData->csound;
}

static Midi gMidi;
/** MIDI functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = &gMidi
  if(midi->readFrom(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi in device %s", dev);
  return -1;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  return 0;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0, byte;
  if(userData) {
    Midi *midi = (Midi *) userData;
    while((byte = midi->getInput()) >= 0) {
      *mbuf++ = (unsigned char) byte;
      if(++n == nbytes) break;
    }
    return n;
  }
  return 0;
}

int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = &gMidi;
  if(midi->writeTo(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi out device %s", dev);
  return -1;
}

int CloseMidiOutDevice(CSOUND *csound, void *userData) {
  return 0;
}

int WriteMidiData(CSOUND *csound, void *userData,
		  const unsigned char *mbuf, int nbytes) {
  if(userData) {
    Midi *midi = (Midi *) userData;
    if(midi->writeOutput((midi_byte_t *)mbuf, nbytes) > 0) return nbytes;
    return 0;
  }
  return 0;
}

void usage(const char *prg) {
  std::cerr << prg << " [options]\n";
  Bela_usage();
  std::cerr << "  --csd=name [-f name]: CSD file name\n";
  std::cerr << "  --help [-h]: help message\n";
}

/**
   Main program: takes Bela options and a --csd=<csdfile>
   option for Csound
*/
int main(int argc, const char *argv[]) {
  CsData csData;
  int c;
  bool res = false;
  BelaInitSettings settings;
  const option opt[] = {{"csd", required_argument, NULL, 'f'},
			{"help", 0, NULL, 'h'},
			{NULL, 0, NULL, 0}};

  Bela_defaultSettings(&settings);
  settings.setup = csound_setup;
  settings.render = csound_render;
  settings.cleanup = csound_cleanup;
  settings.highPerformanceMode = 1;
  settings.interleave = 1;
  settings.analogOutputsPersist = 0;

  while((c = Bela_getopt_long(argc, (char **) argv, "hf", opt, &settings)) >= 0) {
    if (c == 'h') {
      usage(argv[0]);
      return 1;
    } else if (c == 'f') {
      csData.csdfile = optarg;
      res = true;
    } else {
      usage(argv[0]);
      return 1;
    }
  }

  if(res) {
    res = Bela_initAudio(&settings, &csData);
    if(!res){
      if(Bela_startAudio() == 0) {
         while(csData.res == 0)
	   usleep(100000);
      } else
	std::cerr << "error starting audio \n";
      Bela_stopAudio();
    } else
      std::cerr << "error initialising Bela \n";
    Bela_cleanupAudio();
    return 0;
  }
  std::cerr << "no csd provided, use --csd=name \n";
  return 1;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include "gl-extensions.h"

// EXTERNAL INCLUDES
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <dali/integration-api/debug.h>

namespace Dali
{

namespace Internal
{

namespace Adaptor
{

namespace ECoreX
{

GlExtensions::GlExtensions()
  : mInitialized( false )
{
}

GlExtensions::~GlExtensions()
{
}

#if DALI_GLES_VERSION < 30

void GlExtensions::DiscardFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_EXT_discard_framebuffer
  if( mGlDiscardFramebuffer )
  {
    mGlDiscardFramebuffer(target, numAttachments, attachments);
  }
  else
  {
    DALI_LOG_ERROR("Error: glDiscardFramebufferEXT extension is not available\n");
  }
#endif
}

void GlExtensions::GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_OES_get_program_binary
  if (mGlGetProgramBinaryOES)
  {
    mGlGetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
  }
  else
  {
    DALI_LOG_ERROR("Error: glGetProgramBinaryOES extension is not available\n");
    DALI_ASSERT_DEBUG(0);
  }
#endif
}

void GlExtensions::ProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_OES_get_program_binary
  if (mGlProgramBinaryOES)
  {
    mGlProgramBinaryOES(program, binaryFormat, binary, length);
  }
  else
  {
    DALI_LOG_ERROR("Error: glProgramBinaryOES extension is not available\n");
    DALI_ASSERT_DEBUG(0);
  }
#endif
}

void GlExtensions::Initialize()
{
  mInitialized = true;

#ifdef GL_EXT_discard_framebuffer
  mGlDiscardFramebuffer = (PFNGLDISCARDFRAMEBUFFEREXTPROC) eglGetProcAddress("glDiscardFramebufferEXT");
#endif

#ifdef GL_OES_get_program_binary
  mGlGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) eglGetProcAddress("glGetProgramBinaryOES");
  mGlProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) eglGetProcAddress("glProgramBinaryOES");
#endif
}

#endif // DALI_GLES_VERSION < 30

} // namespace ECoreX

} // namespace Adaptor

} // namespace Internal

} // namespace Dali
<commit_msg>More SVACE fixes<commit_after>/*
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include "gl-extensions.h"

// EXTERNAL INCLUDES
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <dali/integration-api/debug.h>

namespace Dali
{

namespace Internal
{

namespace Adaptor
{

namespace ECoreX
{

GlExtensions::GlExtensions()
:
#if DALI_GLES_VERSION < 30
#ifdef GL_EXT_discard_framebuffer
  mGlDiscardFramebuffer( NULL ),
#endif
#ifdef GL_OES_get_program_binary
  mGlGetProgramBinaryOES( NULL ),
  mGlProgramBinaryOES( NULL ),
#endif
#endif // DALI_GLES_VERSION < 30
  mInitialized( false )
{
}

GlExtensions::~GlExtensions()
{
}

#if DALI_GLES_VERSION < 30

void GlExtensions::DiscardFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_EXT_discard_framebuffer
  if( mGlDiscardFramebuffer )
  {
    mGlDiscardFramebuffer(target, numAttachments, attachments);
  }
  else
  {
    DALI_LOG_ERROR("Error: glDiscardFramebufferEXT extension is not available\n");
  }
#endif
}

void GlExtensions::GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_OES_get_program_binary
  if (mGlGetProgramBinaryOES)
  {
    mGlGetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
  }
  else
  {
    DALI_LOG_ERROR("Error: glGetProgramBinaryOES extension is not available\n");
    DALI_ASSERT_DEBUG(0);
  }
#endif
}

void GlExtensions::ProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
{
  // initialize extension on first use as on some hw platforms a context
  // has to be bound for the extensions to return correct pointer
  if( !mInitialized )
  {
    Initialize();
  }

#ifdef GL_OES_get_program_binary
  if (mGlProgramBinaryOES)
  {
    mGlProgramBinaryOES(program, binaryFormat, binary, length);
  }
  else
  {
    DALI_LOG_ERROR("Error: glProgramBinaryOES extension is not available\n");
    DALI_ASSERT_DEBUG(0);
  }
#endif
}

void GlExtensions::Initialize()
{
  mInitialized = true;

#ifdef GL_EXT_discard_framebuffer
  mGlDiscardFramebuffer = (PFNGLDISCARDFRAMEBUFFEREXTPROC) eglGetProcAddress("glDiscardFramebufferEXT");
#endif

#ifdef GL_OES_get_program_binary
  mGlGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) eglGetProcAddress("glGetProgramBinaryOES");
  mGlProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) eglGetProcAddress("glProgramBinaryOES");
#endif
}

#endif // DALI_GLES_VERSION < 30

} // namespace ECoreX

} // namespace Adaptor

} // namespace Internal

} // namespace Dali
<|endoftext|>


<commit_before>#ifndef SHARED_MEMORY_VECTOR_WRAPPER_HPP
#define SHARED_MEMORY_VECTOR_WRAPPER_HPP

#include <boost/assert.hpp>

#include <algorithm>
#include <iterator>
#include <type_traits>
#include <vector>

namespace osrm
{
namespace util
{

template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
{
    DataT *p;

  public:
    explicit ShMemIterator(DataT *x) : p(x) {}
    ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
    ShMemIterator &operator++()
    {
        ++p;
        return *this;
    }
    ShMemIterator operator++(int)
    {
        ShMemIterator tmp(*this);
        operator++();
        return tmp;
    }
    ShMemIterator operator+(std::ptrdiff_t diff)
    {
        ShMemIterator tmp(p + diff);
        return tmp;
    }
    bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
    bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
    DataT &operator*() { return *p; }
};

template <typename DataT> class SharedMemoryWrapper
{
  private:
    DataT *m_ptr;
    std::size_t m_size;

  public:
    SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}

    SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}

    void swap(SharedMemoryWrapper<DataT> &other)
    {
        // BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
        std::swap(m_size, other.m_size);
        std::swap(m_ptr, other.m_ptr);
    }

    DataT &at(const std::size_t index) { return m_ptr[index]; }

    const DataT &at(const std::size_t index) const { return m_ptr[index]; }

    ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }

    ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }

    std::size_t size() const { return m_size; }

    bool empty() const { return 0 == size(); }

    DataT &operator[](const unsigned index)
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        return m_ptr[index];
    }

    const DataT &operator[](const unsigned index) const
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        return m_ptr[index];
    }
};

template <> class SharedMemoryWrapper<bool>
{
  private:
    unsigned *m_ptr;
    std::size_t m_size;

  public:
    SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}

    SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}

    void swap(SharedMemoryWrapper<bool> &other)
    {
        // BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
        std::swap(m_size, other.m_size);
        std::swap(m_ptr, other.m_ptr);
    }

    bool at(const std::size_t index) const
    {
        const std::size_t bucket = index / 32;
        const unsigned offset = static_cast<unsigned>(index % 32);
        return m_ptr[bucket] & (1 << offset);
    }

    std::size_t size() const { return m_size; }

    bool empty() const { return 0 == size(); }

    bool operator[](const unsigned index)
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        const unsigned bucket = index / 32;
        const unsigned offset = index % 32;
        return m_ptr[bucket] & (1 << offset);
    }
};

template <typename DataT, bool UseSharedMemory> struct ShM
{
    using vector = typename std::conditional<UseSharedMemory,
                                             SharedMemoryWrapper<DataT>,
                                             std::vector<DataT>>::type;
};
}
}

#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP
<commit_msg>Fixes shared memory wrapper includes<commit_after>#ifndef SHARED_MEMORY_VECTOR_WRAPPER_HPP
#define SHARED_MEMORY_VECTOR_WRAPPER_HPP

#include <boost/assert.hpp>

#include <cstddef>

#include <algorithm>
#include <iterator>
#include <type_traits>
#include <vector>
#include <utility>

namespace osrm
{
namespace util
{

template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
{
    DataT *p;

  public:
    explicit ShMemIterator(DataT *x) : p(x) {}
    ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
    ShMemIterator &operator++()
    {
        ++p;
        return *this;
    }
    ShMemIterator operator++(int)
    {
        ShMemIterator tmp(*this);
        operator++();
        return tmp;
    }
    ShMemIterator operator+(std::ptrdiff_t diff)
    {
        ShMemIterator tmp(p + diff);
        return tmp;
    }
    bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
    bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
    DataT &operator*() { return *p; }
};

template <typename DataT> class SharedMemoryWrapper
{
  private:
    DataT *m_ptr;
    std::size_t m_size;

  public:
    SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}

    SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}

    void swap(SharedMemoryWrapper<DataT> &other)
    {
        // BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
        std::swap(m_size, other.m_size);
        std::swap(m_ptr, other.m_ptr);
    }

    DataT &at(const std::size_t index) { return m_ptr[index]; }

    const DataT &at(const std::size_t index) const { return m_ptr[index]; }

    ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }

    ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }

    std::size_t size() const { return m_size; }

    bool empty() const { return 0 == size(); }

    DataT &operator[](const unsigned index)
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        return m_ptr[index];
    }

    const DataT &operator[](const unsigned index) const
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        return m_ptr[index];
    }
};

template <> class SharedMemoryWrapper<bool>
{
  private:
    unsigned *m_ptr;
    std::size_t m_size;

  public:
    SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}

    SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}

    void swap(SharedMemoryWrapper<bool> &other)
    {
        // BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
        std::swap(m_size, other.m_size);
        std::swap(m_ptr, other.m_ptr);
    }

    bool at(const std::size_t index) const
    {
        const std::size_t bucket = index / 32;
        const unsigned offset = static_cast<unsigned>(index % 32);
        return m_ptr[bucket] & (1 << offset);
    }

    std::size_t size() const { return m_size; }

    bool empty() const { return 0 == size(); }

    bool operator[](const unsigned index)
    {
        BOOST_ASSERT_MSG(index < m_size, "invalid size");
        const unsigned bucket = index / 32;
        const unsigned offset = index % 32;
        return m_ptr[bucket] & (1 << offset);
    }
};

template <typename DataT, bool UseSharedMemory> struct ShM
{
    using vector = typename std::conditional<UseSharedMemory,
                                             SharedMemoryWrapper<DataT>,
                                             std::vector<DataT>>::type;
};
}
}

#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svtools/PlaceEditDialog.hxx>
#include <svtools/ServerDetailsControls.hxx>

#include <com/sun/star/uno/Sequence.hxx>
#include <officecfg/Office/Common.hxx>
#include <svtools/svtresid.hxx>
#include <vcl/msgbox.hxx>

using namespace com::sun::star::uno;

PlaceEditDialog::PlaceEditDialog(vcl::Window* pParent)
    : ModalDialog(pParent, "PlaceEditDialog", "svt/ui/placeedit.ui")
    , m_xCurrentDetails()
    , m_nCurrentType( 0 )
{
    get( m_pEDServerName, "name" );
    get( m_pLBServerType, "type" );
    get( m_pEDUsername, "login" );
    get( m_pBTOk, "ok" );
    get( m_pBTCancel, "cancel" );
    get( m_pBTDelete, "delete" );
    get( m_pBTRepoRefresh, "repositoriesRefresh" );

    m_pBTOk->SetClickHdl( LINK( this, PlaceEditDialog, OKHdl) );
    m_pBTOk->Enable( false );

    m_pEDServerName->SetModifyHdl( LINK( this, PlaceEditDialog, EditHdl) );

    // This constructor is called when user request a place creation, so
    // delete button is hidden.
    m_pBTDelete->Hide();

    m_pLBServerType->SetSelectHdl( LINK( this, PlaceEditDialog, SelectTypeHdl ) );
    m_pEDUsername->SetModifyHdl( LINK( this, PlaceEditDialog, EditUsernameHdl ) );

    InitDetails( );
}

PlaceEditDialog::PlaceEditDialog(vcl::Window* pParent, const std::shared_ptr<Place>& rPlace)
    : ModalDialog(pParent, "PlaceEditDialog", "svt/ui/placeedit.ui")
    , m_xCurrentDetails( )
{
    get( m_pEDServerName, "name" );
    get( m_pLBServerType, "type" );
    get( m_pEDUsername, "login" );
    get( m_pBTOk, "ok" );
    get( m_pBTCancel, "cancel" );
    get( m_pBTDelete, "delete" );
    get( m_pTypeGrid, "TypeGrid" );

    m_pBTOk->SetClickHdl( LINK( this, PlaceEditDialog, OKHdl) );
    m_pBTDelete->SetClickHdl ( LINK( this, PlaceEditDialog, DelHdl) );

    m_pEDServerName->SetModifyHdl( LINK( this, PlaceEditDialog, EditHdl) );
    m_pLBServerType->SetSelectHdl( LINK( this, PlaceEditDialog, SelectTypeHdl ) );

    InitDetails( );

    m_pEDServerName->SetText(rPlace->GetName());

    // Fill the boxes with the URL parts
    bool bSuccess = false;
    for (size_t i = 0 ; i < m_aDetailsContainers.size( ) && !bSuccess; ++i)
    {
        INetURLObject& rUrl = rPlace->GetUrlObject();
        bSuccess = m_aDetailsContainers[i]->setUrl( rUrl );
        if ( bSuccess )
        {
            m_pLBServerType->SelectEntryPos( i );
            SelectTypeHdl( m_pLBServerType );

            // Fill the Username field
            if ( rUrl.HasUserData( ) )
                m_pEDUsername->SetText( INetURLObject::decode( rUrl.GetUser( ),
                                                              INetURLObject::DECODE_WITH_CHARSET ) );
        }
    }

    // In edit mode user can't change connection type
    m_pTypeGrid->Hide();
}

PlaceEditDialog::~PlaceEditDialog()
{
    disposeOnce();
}

void PlaceEditDialog::dispose()
{
    m_pEDServerName.clear();
    m_pLBServerType.clear();
    m_pEDUsername.clear();
    m_pBTOk.clear();
    m_pBTCancel.clear();
    m_pBTDelete.clear();
    ModalDialog::dispose();
}

OUString PlaceEditDialog::GetServerUrl()
{
    OUString sUrl;
    if (m_xCurrentDetails.get())
    {
        INetURLObject aUrl = m_xCurrentDetails->getUrl();
        OUString sUsername = OUString( m_pEDUsername->GetText( ) ).trim( );
        if ( !sUsername.isEmpty( ) )
            aUrl.SetUser( sUsername );
        if ( !aUrl.HasError( ) )
            sUrl = aUrl.GetMainURL( INetURLObject::NO_DECODE );
    }

    return sUrl;
}

std::shared_ptr<Place> PlaceEditDialog::GetPlace()
{
    return std::make_shared<Place>(m_pEDServerName->GetText(), GetServerUrl(), true);
}

void PlaceEditDialog::InitDetails( )
{
    // Create CMIS controls for each server type

    Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();

    // Load the ServerType entries
    bool bSkipGDrive = OUString( GDRIVE_CLIENT_ID ).isEmpty() ||
                       OUString( GDRIVE_CLIENT_SECRET ).isEmpty();
    bool bSkipAlfresco = OUString( ALFRESCO_CLOUD_CLIENT_ID ).isEmpty() ||
                       OUString( ALFRESCO_CLOUD_CLIENT_SECRET ).isEmpty();
    bool bSkipOneDrive= OUString( ONEDRIVE_CLIENT_ID ).isEmpty() ||
                       OUString( ONEDRIVE_CLIENT_SECRET ).isEmpty();

    Sequence< OUString > aTypesUrlsList( officecfg::Office::Common::Misc::CmisServersUrls::get( xContext ) );
    Sequence< OUString > aTypesNamesList( officecfg::Office::Common::Misc::CmisServersNames::get( xContext ) );

    unsigned int nPos = 0;
    for ( sal_Int32 i = 0; i < aTypesUrlsList.getLength( ) && aTypesNamesList.getLength( ); ++i )
    {
        OUString sUrl = aTypesUrlsList[i];
        if ( !( sUrl == GDRIVE_BASE_URL && bSkipGDrive ) &&
             !( sUrl.startsWith( ALFRESCO_CLOUD_BASE_URL ) && bSkipAlfresco ) &&
             !( sUrl == ONEDRIVE_BASE_URL && bSkipOneDrive ) )
        {
            nPos = m_pLBServerType->InsertEntry( aTypesNamesList[i], nPos );

            std::shared_ptr<DetailsContainer> xCmisDetails(std::make_shared<CmisDetailsContainer>(this, sUrl));
            xCmisDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
            m_aDetailsContainers.push_back(xCmisDetails);

            nPos++;
        }
    }

    // Create WebDAV / FTP / SSH details control
    std::shared_ptr<DetailsContainer> xDavDetails(std::make_shared<DavDetailsContainer>(this));
    xDavDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xDavDetails);

    std::shared_ptr<DetailsContainer> xFtpDetails(std::make_shared<HostDetailsContainer>(this, 21, "ftp"));
    xFtpDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xFtpDetails);

    std::shared_ptr<DetailsContainer> xSshDetails(std::make_shared<HostDetailsContainer>(this, 22, "ssh"));
    xSshDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xSshDetails);

    // Create Windows Share control
    std::shared_ptr<DetailsContainer> xSmbDetails(std::make_shared<SmbDetailsContainer>(this));
    xSmbDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xSmbDetails);

    // Set default to first value
    m_pLBServerType->SelectEntryPos( 0 );
    SelectTypeHdl( m_pLBServerType );
}

IMPL_LINK ( PlaceEditDialog,  OKHdl, Button *, )
{
    if ( m_xCurrentDetails.get() )
    {
        OUString sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DECODE_WITH_CHARSET );
        OUString sGDriveHost( GDRIVE_BASE_URL );
        OUString sAlfrescoHost( ALFRESCO_CLOUD_BASE_URL );
        OUString sOneDriveHost( ONEDRIVE_BASE_URL );

        if ( sUrl.compareTo( sGDriveHost, sGDriveHost.getLength() ) == 0
           || sUrl.compareTo( sAlfrescoHost, sAlfrescoHost.getLength() ) == 0
           || sUrl.compareTo( sOneDriveHost, sOneDriveHost.getLength() ) == 0 )
        {
            m_pBTRepoRefresh->Click();

            sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DECODE_WITH_CHARSET );
            INetURLObject aHostUrl( sUrl );
            OUString sRepoId = aHostUrl.GetMark();

            if ( !sRepoId.isEmpty() )
            {
                EndDialog( RET_OK );
            }
            else
            {
                // TODO: repository id missing. Auth error?
            }
        }
        else
        {
            EndDialog( RET_OK );
        }
    }

    return 1;
}

IMPL_LINK ( PlaceEditDialog, DelHdl, Button *, )
{
    // ReUsing existing symbols...
    EndDialog( RET_NO );
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, EditHdl )
{
    OUString sUrl = GetServerUrl( );
    OUString sName = OUString( m_pEDServerName->GetText() ).trim( );
    m_pBTOk->Enable( !sName.isEmpty( ) && !sUrl.isEmpty( ) );
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, EditUsernameHdl )
{
    for ( std::vector< std::shared_ptr< DetailsContainer > >::iterator it = m_aDetailsContainers.begin( );
            it != m_aDetailsContainers.end( ); ++it )
    {
        ( *it )->setUsername( OUString( m_pEDUsername->GetText() ) );
    }
    EditHdl(NULL);
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, SelectTypeHdl )
{
    if ( m_pLBServerType->GetSelectEntry() == "--------------------" )
    {
        if( !m_pLBServerType->IsTravelSelect() )
            m_pLBServerType->SelectEntryPos( m_nCurrentType );
        else
            m_pLBServerType->SetNoSelection();

        return 0;
    }

    if (m_xCurrentDetails.get())
        m_xCurrentDetails->show(false);

    sal_uInt16 nPos = m_pLBServerType->GetSelectEntryPos( );
    m_xCurrentDetails = m_aDetailsContainers[nPos];
    m_nCurrentType = nPos;

    m_xCurrentDetails->show(true);

    SetSizePixel(GetOptimalSize());

    EditHdl(NULL);

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Separator should not be the default selection<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svtools/PlaceEditDialog.hxx>
#include <svtools/ServerDetailsControls.hxx>

#include <com/sun/star/uno/Sequence.hxx>
#include <officecfg/Office/Common.hxx>
#include <svtools/svtresid.hxx>
#include <vcl/msgbox.hxx>

using namespace com::sun::star::uno;

PlaceEditDialog::PlaceEditDialog(vcl::Window* pParent)
    : ModalDialog(pParent, "PlaceEditDialog", "svt/ui/placeedit.ui")
    , m_xCurrentDetails()
    , m_nCurrentType( 0 )
{
    get( m_pEDServerName, "name" );
    get( m_pLBServerType, "type" );
    get( m_pEDUsername, "login" );
    get( m_pBTOk, "ok" );
    get( m_pBTCancel, "cancel" );
    get( m_pBTDelete, "delete" );
    get( m_pBTRepoRefresh, "repositoriesRefresh" );

    m_pBTOk->SetClickHdl( LINK( this, PlaceEditDialog, OKHdl) );
    m_pBTOk->Enable( false );

    m_pEDServerName->SetModifyHdl( LINK( this, PlaceEditDialog, EditHdl) );

    // This constructor is called when user request a place creation, so
    // delete button is hidden.
    m_pBTDelete->Hide();

    m_pLBServerType->SetSelectHdl( LINK( this, PlaceEditDialog, SelectTypeHdl ) );
    m_pEDUsername->SetModifyHdl( LINK( this, PlaceEditDialog, EditUsernameHdl ) );

    InitDetails( );
}

PlaceEditDialog::PlaceEditDialog(vcl::Window* pParent, const std::shared_ptr<Place>& rPlace)
    : ModalDialog(pParent, "PlaceEditDialog", "svt/ui/placeedit.ui")
    , m_xCurrentDetails( )
{
    get( m_pEDServerName, "name" );
    get( m_pLBServerType, "type" );
    get( m_pEDUsername, "login" );
    get( m_pBTOk, "ok" );
    get( m_pBTCancel, "cancel" );
    get( m_pBTDelete, "delete" );
    get( m_pTypeGrid, "TypeGrid" );

    m_pBTOk->SetClickHdl( LINK( this, PlaceEditDialog, OKHdl) );
    m_pBTDelete->SetClickHdl ( LINK( this, PlaceEditDialog, DelHdl) );

    m_pEDServerName->SetModifyHdl( LINK( this, PlaceEditDialog, EditHdl) );
    m_pLBServerType->SetSelectHdl( LINK( this, PlaceEditDialog, SelectTypeHdl ) );

    InitDetails( );

    m_pEDServerName->SetText(rPlace->GetName());

    // Fill the boxes with the URL parts
    bool bSuccess = false;
    for (size_t i = 0 ; i < m_aDetailsContainers.size( ) && !bSuccess; ++i)
    {
        INetURLObject& rUrl = rPlace->GetUrlObject();
        bSuccess = m_aDetailsContainers[i]->setUrl( rUrl );
        if ( bSuccess )
        {
            m_pLBServerType->SelectEntryPos( i );
            SelectTypeHdl( m_pLBServerType );

            // Fill the Username field
            if ( rUrl.HasUserData( ) )
                m_pEDUsername->SetText( INetURLObject::decode( rUrl.GetUser( ),
                                                              INetURLObject::DECODE_WITH_CHARSET ) );
        }
    }

    // In edit mode user can't change connection type
    m_pTypeGrid->Hide();
}

PlaceEditDialog::~PlaceEditDialog()
{
    disposeOnce();
}

void PlaceEditDialog::dispose()
{
    m_pEDServerName.clear();
    m_pLBServerType.clear();
    m_pEDUsername.clear();
    m_pBTOk.clear();
    m_pBTCancel.clear();
    m_pBTDelete.clear();
    ModalDialog::dispose();
}

OUString PlaceEditDialog::GetServerUrl()
{
    OUString sUrl;
    if (m_xCurrentDetails.get())
    {
        INetURLObject aUrl = m_xCurrentDetails->getUrl();
        OUString sUsername = OUString( m_pEDUsername->GetText( ) ).trim( );
        if ( !sUsername.isEmpty( ) )
            aUrl.SetUser( sUsername );
        if ( !aUrl.HasError( ) )
            sUrl = aUrl.GetMainURL( INetURLObject::NO_DECODE );
    }

    return sUrl;
}

std::shared_ptr<Place> PlaceEditDialog::GetPlace()
{
    return std::make_shared<Place>(m_pEDServerName->GetText(), GetServerUrl(), true);
}

void PlaceEditDialog::InitDetails( )
{
    // Create CMIS controls for each server type

    Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();

    // Load the ServerType entries
    bool bSkipGDrive = OUString( GDRIVE_CLIENT_ID ).isEmpty() ||
                       OUString( GDRIVE_CLIENT_SECRET ).isEmpty();
    bool bSkipAlfresco = OUString( ALFRESCO_CLOUD_CLIENT_ID ).isEmpty() ||
                       OUString( ALFRESCO_CLOUD_CLIENT_SECRET ).isEmpty();
    bool bSkipOneDrive= OUString( ONEDRIVE_CLIENT_ID ).isEmpty() ||
                       OUString( ONEDRIVE_CLIENT_SECRET ).isEmpty();

    Sequence< OUString > aTypesUrlsList( officecfg::Office::Common::Misc::CmisServersUrls::get( xContext ) );
    Sequence< OUString > aTypesNamesList( officecfg::Office::Common::Misc::CmisServersNames::get( xContext ) );

    unsigned int nPos = 0;
    for ( sal_Int32 i = 0; i < aTypesUrlsList.getLength( ) && aTypesNamesList.getLength( ); ++i )
    {
        OUString sUrl = aTypesUrlsList[i];
        if ( !( sUrl == GDRIVE_BASE_URL && bSkipGDrive ) &&
             !( sUrl.startsWith( ALFRESCO_CLOUD_BASE_URL ) && bSkipAlfresco ) &&
             !( sUrl == ONEDRIVE_BASE_URL && bSkipOneDrive ) )
        {
            nPos = m_pLBServerType->InsertEntry( aTypesNamesList[i], nPos );

            std::shared_ptr<DetailsContainer> xCmisDetails(std::make_shared<CmisDetailsContainer>(this, sUrl));
            xCmisDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
            m_aDetailsContainers.push_back(xCmisDetails);

            nPos++;
        }
    }

    // Create WebDAV / FTP / SSH details control
    std::shared_ptr<DetailsContainer> xDavDetails(std::make_shared<DavDetailsContainer>(this));
    xDavDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xDavDetails);

    std::shared_ptr<DetailsContainer> xFtpDetails(std::make_shared<HostDetailsContainer>(this, 21, "ftp"));
    xFtpDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xFtpDetails);

    std::shared_ptr<DetailsContainer> xSshDetails(std::make_shared<HostDetailsContainer>(this, 22, "ssh"));
    xSshDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xSshDetails);

    // Create Windows Share control
    std::shared_ptr<DetailsContainer> xSmbDetails(std::make_shared<SmbDetailsContainer>(this));
    xSmbDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
    m_aDetailsContainers.push_back(xSmbDetails);

    // Set default to first value
    m_pLBServerType->SelectEntryPos( 0 );

    if ( m_pLBServerType->GetSelectEntry() == "--------------------" )
        m_pLBServerType->SelectEntryPos( 1 );

    SelectTypeHdl( m_pLBServerType );
}

IMPL_LINK ( PlaceEditDialog,  OKHdl, Button *, )
{
    if ( m_xCurrentDetails.get() )
    {
        OUString sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DECODE_WITH_CHARSET );
        OUString sGDriveHost( GDRIVE_BASE_URL );
        OUString sAlfrescoHost( ALFRESCO_CLOUD_BASE_URL );
        OUString sOneDriveHost( ONEDRIVE_BASE_URL );

        if ( sUrl.compareTo( sGDriveHost, sGDriveHost.getLength() ) == 0
           || sUrl.compareTo( sAlfrescoHost, sAlfrescoHost.getLength() ) == 0
           || sUrl.compareTo( sOneDriveHost, sOneDriveHost.getLength() ) == 0 )
        {
            m_pBTRepoRefresh->Click();

            sUrl = m_xCurrentDetails->getUrl().GetHost( INetURLObject::DECODE_WITH_CHARSET );
            INetURLObject aHostUrl( sUrl );
            OUString sRepoId = aHostUrl.GetMark();

            if ( !sRepoId.isEmpty() )
            {
                EndDialog( RET_OK );
            }
            else
            {
                // TODO: repository id missing. Auth error?
            }
        }
        else
        {
            EndDialog( RET_OK );
        }
    }

    return 1;
}

IMPL_LINK ( PlaceEditDialog, DelHdl, Button *, )
{
    // ReUsing existing symbols...
    EndDialog( RET_NO );
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, EditHdl )
{
    OUString sUrl = GetServerUrl( );
    OUString sName = OUString( m_pEDServerName->GetText() ).trim( );
    m_pBTOk->Enable( !sName.isEmpty( ) && !sUrl.isEmpty( ) );
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, EditUsernameHdl )
{
    for ( std::vector< std::shared_ptr< DetailsContainer > >::iterator it = m_aDetailsContainers.begin( );
            it != m_aDetailsContainers.end( ); ++it )
    {
        ( *it )->setUsername( OUString( m_pEDUsername->GetText() ) );
    }
    EditHdl(NULL);
    return 1;
}

IMPL_LINK_NOARG( PlaceEditDialog, SelectTypeHdl )
{
    if ( m_pLBServerType->GetSelectEntry() == "--------------------" )
    {
        if( !m_pLBServerType->IsTravelSelect() )
            m_pLBServerType->SelectEntryPos( m_nCurrentType );
        else
            m_pLBServerType->SetNoSelection();

        return 0;
    }

    if (m_xCurrentDetails.get())
        m_xCurrentDetails->show(false);

    sal_uInt16 nPos = m_pLBServerType->GetSelectEntryPos( );
    m_xCurrentDetails = m_aDetailsContainers[nPos];
    m_nCurrentType = nPos;

    m_xCurrentDetails->show(true);

    SetSizePixel(GetOptimalSize());

    EditHdl(NULL);

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>clear<commit_after><|endoftext|>