<commit_before>/*
** Copyright 2009-2013,2015-2017 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include <limits>
#include <memory>
#include <sstream>
#include "com/centreon/broker/config/applier/state.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/multiplexing/engine.hh"
#include "com/centreon/broker/multiplexing/muxer.hh"
#include "com/centreon/broker/persistent_file.hh"
#include "com/centreon/broker/misc/string.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::multiplexing;

unsigned int muxer::_event_queue_max_size = std::numeric_limits<unsigned int>::max();

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] name        Name associated to this muxer. It is used to
 *                         create on-disk files.
 *  @param[in] persistent  Whether or not this muxer should backup
 *                         unprocessed events in a persistent storage.
 */
muxer::muxer(
         std::string const& name,
         bool persistent)
  : _events_size(0),
    _name(name),
    _persistent(persistent) {
  // Load head queue file back in memory.
  if (_persistent) {
    try {
      std::auto_ptr<io::stream>
        mf(new persistent_file(_memory_file()));
      misc::shared_ptr<io::data> e;
      while (true) {
        e.clear();
        mf->read(e, 0);
        if (!e.isNull()) {
          _events.push_back(e);
          ++_events_size;
        }
      }
    }
    catch (io::exceptions::shutdown const& e) {
      // Memory file was properly read back in memory.
      (void)e;
    }
  }

  // Load queue file back in memory.
  try {
    _file.reset(new persistent_file(_queue_file()));
    misc::shared_ptr<io::data> e;
    // The following do-while might read an extra event from the queue
    // file back in memory. However this is necessary to ensure that a
    // read() operation was done on the queue file and prevent it from
    // being open in case it is empty.
    do {
      e.clear();
      _get_event_from_file(e);
      if (e.isNull())
        break ;
      _push_to_queue(e);
    } while (_events_size < event_queue_max_size());
  }
  catch (io::exceptions::shutdown const& e) {
    // Queue file was entirely read back.
    (void)e;
  }
  _pos = _events.begin();

  // Log messages.
  logging::info(logging::low)
    << "multiplexing: '" << _name << "' start with " << _events_size
    << " in queue and the queue file is "
    << (_file.get() ? "enable" : "disable");
}

/**
 *  Destructor.
 */
muxer::~muxer() {
  _clean();
}

/**
 *  Acknowledge events.
 *
 *  @param[in] count  Number of events to acknowledge.
 */
void muxer::ack_events(int count) {
  // Remove acknowledged events.
  logging::debug(logging::low)
    << "multiplexing: acknowledging " << count << " events from "
    << _name << " event queue";
  QMutexLocker lock(&_mutex);
  for (int i(0); (i < count) && !_events.empty(); ++i) {
    _events.pop_front();
    --_events_size;
  }

  // Fill memory from file.
  misc::shared_ptr<io::data> e;
  while (_events_size < event_queue_max_size()) {
    e.clear();
    _get_event_from_file(e);
    if (e.isNull())
      break ;
    _push_to_queue(e);
  }

  return ;
}

/**
 *  Set the maximume event queue size.
 *
 *  @param[in] max  The size limit.
 */
void muxer::event_queue_max_size(unsigned int max) throw () {
  if (!max)
    max = std::numeric_limits<unsigned int>::max();
  _event_queue_max_size = max;
  return ;
}

/**
 *  Get the maximum event queue size.
 *
 *  @return The size limit.
 */
unsigned int muxer::event_queue_max_size() throw () {
  return (_event_queue_max_size);
}

/**
 *  Add a new event to the internal event list.
 *
 *  @param[in] event Event to add.
 */
void muxer::publish(misc::shared_ptr<io::data> const& event) {
  if (!event.isNull()) {
    QMutexLocker lock(&_mutex);
    // Check if we should process this event.
    if (_write_filters.find(event->type()) == _write_filters.end())
      return ;
    // Check if the event queue limit is reach.
    if (_events_size >= event_queue_max_size()) {
      // Try to create file if is necessary.
      if (!_file.get())
        _file.reset(new persistent_file(_queue_file()));
      _file->write(event);
    }
    else
      _push_to_queue(event);
  }
  return ;
}

/**
 *  Get the next available event without waiting more than timeout.
 *
 *  @param[out] event      Next available event.
 *  @param[in]  deadline   Date limit.
 *
 *  @return Respect io::stream::read()'s return value.
 */
bool muxer::read(
              misc::shared_ptr<io::data>& event,
              time_t deadline) {
  bool timed_out(false);
  QMutexLocker lock(&_mutex);

  // No data is directly available.
  if (_pos == _events.end()) {
    // Wait a while if subscriber was not shutdown.
    if ((time_t)-1 == deadline)
      _cv.wait(&_mutex);
    else {
      time_t now(time(NULL));
      if (now < deadline)
        timed_out = !_cv.wait(&_mutex, (deadline - now) * 1000);
      else
        timed_out = true;
    }
    if (_pos != _events.end()) {
      event = *_pos;
      ++_pos;
      lock.unlock();
      if (!event.isNull())
        timed_out = false;
    }
    else
      event.clear();
  }
  // Data is available, no need to wait.
  else {
    event = *_pos;
    ++_pos;
    lock.unlock();
  }
  return (!timed_out);
}

/**
 *  Set the read filters.
 *
 *  @param[in] fltrs  Read filters. That is read() will return only
 *                    events which type() is available in this set.
 */
void muxer::set_read_filters(muxer::filters const& fltrs) {
  _read_filters = fltrs;
  return ;
}

/**
 *  Set the write filters.
 *
 *  @param[in] fltrs  Write filters. That is any submitted through
 *                    write() must be in this set otherwise it won't be
 *                    multiplexed.
 */
void muxer::set_write_filters(muxer::filters const& fltrs) {
  _write_filters = fltrs;
  return ;
}

/**
 *  Get the read filters.
 *
 *  @return  The read filters.
 */
muxer::filters const& muxer::get_read_filters() const {
  return (_read_filters);
}

/**
 *  Get the write filters.
 *
 *  @return  The write filters.
 */
muxer::filters const& muxer::get_write_filters() const {
  return (_write_filters);
}

/**
 *  Get the size of the event queue.
 *
 *  @return  The size of the event queue.
 */
unsigned int muxer::get_event_queue_size() const {
  QMutexLocker lock(&_mutex);
  return (_events.size());
}

/**
 *  Reprocess non-acknowledged events.
 */
void muxer::nack_events() {
  logging::debug(logging::low)
    << "multiplexing: reprocessing unacknowledged events from "
    << _name << " event queue";
  QMutexLocker lock(&_mutex);
  _pos = _events.begin();
  return ;
}

/**
 *  Generate statistics about the subscriber.
 *
 *  @param[out] buffer Output buffer.
 */
void muxer::statistics(io::properties& tree) const {
  // Lock object.
  QMutexLocker lock(&_mutex);

  // Queue file mode.
  bool queue_file_enabled(_file.get());
  tree.add_property(
         "queue_file_enabled",
         io::property(
               "queue_file_enabled",
               queue_file_enabled ? "yes" : "no"));
  if (queue_file_enabled) {
    io::properties queue_file;
    _file->statistics(queue_file);
    tree.add_child(queue_file, "queue_file");
  }

  // Unacknowledged events count.
  int unacknowledged(0);
  for (std::list<misc::shared_ptr<io::data> >::const_iterator
         it(_events.begin());
       it != _pos;
       ++it)
    ++unacknowledged;
  tree.add_property(
         "unacknowledged_events",
         io::property(
               "unacknowledged_events",
               misc::string::get(unacknowledged)));

  return ;
}

/**
 *  Wake all threads waiting on this subscriber.
 */
void muxer::wake() {
  QMutexLocker lock(&_mutex);
  _cv.wakeAll();
  return ;
}

/**
 *  Send an event to multiplexing.
 *
 *  @param[in] d  Event to multiplex.
 */
int muxer::write(misc::shared_ptr<io::data> const& d) {
  if (!d.isNull()
      && (_read_filters.find(d->type()) != _read_filters.end()))
    engine::instance().publish(d);
  return (1);
}

/**
 *  Get the memory file name associated with this muxer.
 *
 *  @param[in] name  Name of this muxer.
 *
 *  @return  The memory file name associated with this muxer.
 */
std::string muxer::memory_file(std::string const& name) {
  std::string retval(config::applier::state::instance().cache_dir());
  retval.append(".memory.");
  retval.append(name);
  return (retval);
}

/**
 *  Get the queue file name associated with this muxer.
 *
 *  @param[in] name  Name of this muxer.
 *
 *  @return  The queue file name associated with this muxer.
 */
std::string muxer::queue_file(std::string const& name) {
  std::string retval(config::applier::state::instance().cache_dir());
  retval.append(".queue.");
  retval.append(name);
  return (retval);
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Release all events stored within the internal list.
 */
void muxer::_clean() {
  QMutexLocker lock(&_mutex);
  _file.reset();
  if (_persistent && !_events.empty()) {
    try {
      std::auto_ptr<io::stream>
        mf(new persistent_file(_memory_file()));
      while (!_events.empty()) {
        mf->write(_events.front());
        _events.pop_front();
        --_events_size;
      }
    }
    catch (std::exception const& e) {
      logging::error(logging::high)
        << "multiplexing: could not backup memory queue of '" << _name
        << "': " << e.what();
    }
  }
  _events.clear();
  _events_size = 0;
  return ;
}

/**
 *  Get event from retention file. Warning: lock _mutex before using
 *  this function.
 *
 *  @param[out] event  Last event available. Null if none is available.
 */
void muxer::_get_event_from_file(misc::shared_ptr<io::data>& event) {
  event.clear();
  // If file exist, try to get the last event.
  if (_file.get()) {
    try {
      do {
        _file->read(event);
      } while (event.isNull());
    }
    catch (io::exceptions::shutdown const& e) {
      // The file end was reach.
      (void)e;
      _file.reset();
    }
  }
  return ;
}

/**
 *  Get memory file path.
 *
 *  @return Path to the memory file.
 */
std::string muxer::_memory_file() const {
  return (memory_file(_name));
}

/**
 *  Push event to queue.
 *
 *  @param[in] event  New event.
 */
void muxer::_push_to_queue(misc::shared_ptr<io::data> const& event) {
  bool pos_has_no_more_to_read(_pos == _events.end());
  _events.push_back(event);
  ++_events_size;
  if (pos_has_no_more_to_read) {
    _pos = --_events.end();
    _cv.wakeOne();
  }
  return ;
}

/**
 *  Get queue file path.
 *
 *  @return Path to the queue file.
 */
std::string muxer::_queue_file() const {
  return (queue_file(_name));
}
<commit_msg>core: prevent acknowledgement of too many events.<commit_after>/*
** Copyright 2009-2013,2015-2017 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include <limits>
#include <memory>
#include <sstream>
#include "com/centreon/broker/config/applier/state.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/multiplexing/engine.hh"
#include "com/centreon/broker/multiplexing/muxer.hh"
#include "com/centreon/broker/persistent_file.hh"
#include "com/centreon/broker/misc/string.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::multiplexing;

unsigned int muxer::_event_queue_max_size = std::numeric_limits<unsigned int>::max();

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] name        Name associated to this muxer. It is used to
 *                         create on-disk files.
 *  @param[in] persistent  Whether or not this muxer should backup
 *                         unprocessed events in a persistent storage.
 */
muxer::muxer(
         std::string const& name,
         bool persistent)
  : _events_size(0),
    _name(name),
    _persistent(persistent) {
  // Load head queue file back in memory.
  if (_persistent) {
    try {
      std::auto_ptr<io::stream>
        mf(new persistent_file(_memory_file()));
      misc::shared_ptr<io::data> e;
      while (true) {
        e.clear();
        mf->read(e, 0);
        if (!e.isNull()) {
          _events.push_back(e);
          ++_events_size;
        }
      }
    }
    catch (io::exceptions::shutdown const& e) {
      // Memory file was properly read back in memory.
      (void)e;
    }
  }

  // Load queue file back in memory.
  try {
    _file.reset(new persistent_file(_queue_file()));
    misc::shared_ptr<io::data> e;
    // The following do-while might read an extra event from the queue
    // file back in memory. However this is necessary to ensure that a
    // read() operation was done on the queue file and prevent it from
    // being open in case it is empty.
    do {
      e.clear();
      _get_event_from_file(e);
      if (e.isNull())
        break ;
      _events.push_back(e);
      ++_events_size;
    } while (_events_size < event_queue_max_size());
  }
  catch (io::exceptions::shutdown const& e) {
    // Queue file was entirely read back.
    (void)e;
  }
  _pos = _events.begin();

  // Log messages.
  logging::info(logging::low)
    << "multiplexing: '" << _name << "' start with " << _events_size
    << " in queue and the queue file is "
    << (_file.get() ? "enable" : "disable");
}

/**
 *  Destructor.
 */
muxer::~muxer() {
  _clean();
}

/**
 *  Acknowledge events.
 *
 *  @param[in] count  Number of events to acknowledge.
 */
void muxer::ack_events(int count) {
  // Remove acknowledged events.
  logging::debug(logging::low)
    << "multiplexing: acknowledging " << count << " events from "
    << _name << " event queue";
  QMutexLocker lock(&_mutex);
  for (int i(0); (i < count) && !_events.empty(); ++i) {
    if (_events.begin() == _pos) {
      logging::error(logging::high) << "multiplexing: attempt to "
        << "acknowledge more events than available in " << _name
        << " event queue: " << count << " requested, " << i
        << " acknowledged";
      break ;
    }
    _events.pop_front();
    --_events_size;
  }

  // Fill memory from file.
  misc::shared_ptr<io::data> e;
  while (_events_size < event_queue_max_size()) {
    e.clear();
    _get_event_from_file(e);
    if (e.isNull())
      break ;
    _push_to_queue(e);
  }

  return ;
}

/**
 *  Set the maximume event queue size.
 *
 *  @param[in] max  The size limit.
 */
void muxer::event_queue_max_size(unsigned int max) throw () {
  if (!max)
    max = std::numeric_limits<unsigned int>::max();
  _event_queue_max_size = max;
  return ;
}

/**
 *  Get the maximum event queue size.
 *
 *  @return The size limit.
 */
unsigned int muxer::event_queue_max_size() throw () {
  return (_event_queue_max_size);
}

/**
 *  Add a new event to the internal event list.
 *
 *  @param[in] event Event to add.
 */
void muxer::publish(misc::shared_ptr<io::data> const& event) {
  if (!event.isNull()) {
    QMutexLocker lock(&_mutex);
    // Check if we should process this event.
    if (_write_filters.find(event->type()) == _write_filters.end())
      return ;
    // Check if the event queue limit is reach.
    if (_events_size >= event_queue_max_size()) {
      // Try to create file if is necessary.
      if (!_file.get())
        _file.reset(new persistent_file(_queue_file()));
      _file->write(event);
    }
    else
      _push_to_queue(event);
  }
  return ;
}

/**
 *  Get the next available event without waiting more than timeout.
 *
 *  @param[out] event      Next available event.
 *  @param[in]  deadline   Date limit.
 *
 *  @return Respect io::stream::read()'s return value.
 */
bool muxer::read(
              misc::shared_ptr<io::data>& event,
              time_t deadline) {
  bool timed_out(false);
  QMutexLocker lock(&_mutex);

  // No data is directly available.
  if (_pos == _events.end()) {
    // Wait a while if subscriber was not shutdown.
    if ((time_t)-1 == deadline)
      _cv.wait(&_mutex);
    else {
      time_t now(time(NULL));
      if (now < deadline)
        timed_out = !_cv.wait(&_mutex, (deadline - now) * 1000);
      else
        timed_out = true;
    }
    if (_pos != _events.end()) {
      event = *_pos;
      ++_pos;
      lock.unlock();
      if (!event.isNull())
        timed_out = false;
    }
    else
      event.clear();
  }
  // Data is available, no need to wait.
  else {
    event = *_pos;
    ++_pos;
    lock.unlock();
  }
  return (!timed_out);
}

/**
 *  Set the read filters.
 *
 *  @param[in] fltrs  Read filters. That is read() will return only
 *                    events which type() is available in this set.
 */
void muxer::set_read_filters(muxer::filters const& fltrs) {
  _read_filters = fltrs;
  return ;
}

/**
 *  Set the write filters.
 *
 *  @param[in] fltrs  Write filters. That is any submitted through
 *                    write() must be in this set otherwise it won't be
 *                    multiplexed.
 */
void muxer::set_write_filters(muxer::filters const& fltrs) {
  _write_filters = fltrs;
  return ;
}

/**
 *  Get the read filters.
 *
 *  @return  The read filters.
 */
muxer::filters const& muxer::get_read_filters() const {
  return (_read_filters);
}

/**
 *  Get the write filters.
 *
 *  @return  The write filters.
 */
muxer::filters const& muxer::get_write_filters() const {
  return (_write_filters);
}

/**
 *  Get the size of the event queue.
 *
 *  @return  The size of the event queue.
 */
unsigned int muxer::get_event_queue_size() const {
  QMutexLocker lock(&_mutex);
  return (_events.size());
}

/**
 *  Reprocess non-acknowledged events.
 */
void muxer::nack_events() {
  logging::debug(logging::low)
    << "multiplexing: reprocessing unacknowledged events from "
    << _name << " event queue";
  QMutexLocker lock(&_mutex);
  _pos = _events.begin();
  return ;
}

/**
 *  Generate statistics about the subscriber.
 *
 *  @param[out] buffer Output buffer.
 */
void muxer::statistics(io::properties& tree) const {
  // Lock object.
  QMutexLocker lock(&_mutex);

  // Queue file mode.
  bool queue_file_enabled(_file.get());
  tree.add_property(
         "queue_file_enabled",
         io::property(
               "queue_file_enabled",
               queue_file_enabled ? "yes" : "no"));
  if (queue_file_enabled) {
    io::properties queue_file;
    _file->statistics(queue_file);
    tree.add_child(queue_file, "queue_file");
  }

  // Unacknowledged events count.
  int unacknowledged(0);
  for (std::list<misc::shared_ptr<io::data> >::const_iterator
         it(_events.begin());
       it != _pos;
       ++it)
    ++unacknowledged;
  tree.add_property(
         "unacknowledged_events",
         io::property(
               "unacknowledged_events",
               misc::string::get(unacknowledged)));

  return ;
}

/**
 *  Wake all threads waiting on this subscriber.
 */
void muxer::wake() {
  QMutexLocker lock(&_mutex);
  _cv.wakeAll();
  return ;
}

/**
 *  Send an event to multiplexing.
 *
 *  @param[in] d  Event to multiplex.
 */
int muxer::write(misc::shared_ptr<io::data> const& d) {
  if (!d.isNull()
      && (_read_filters.find(d->type()) != _read_filters.end()))
    engine::instance().publish(d);
  return (1);
}

/**
 *  Get the memory file name associated with this muxer.
 *
 *  @param[in] name  Name of this muxer.
 *
 *  @return  The memory file name associated with this muxer.
 */
std::string muxer::memory_file(std::string const& name) {
  std::string retval(config::applier::state::instance().cache_dir());
  retval.append(".memory.");
  retval.append(name);
  return (retval);
}

/**
 *  Get the queue file name associated with this muxer.
 *
 *  @param[in] name  Name of this muxer.
 *
 *  @return  The queue file name associated with this muxer.
 */
std::string muxer::queue_file(std::string const& name) {
  std::string retval(config::applier::state::instance().cache_dir());
  retval.append(".queue.");
  retval.append(name);
  return (retval);
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Release all events stored within the internal list.
 */
void muxer::_clean() {
  QMutexLocker lock(&_mutex);
  _file.reset();
  if (_persistent && !_events.empty()) {
    try {
      std::auto_ptr<io::stream>
        mf(new persistent_file(_memory_file()));
      while (!_events.empty()) {
        mf->write(_events.front());
        _events.pop_front();
        --_events_size;
      }
    }
    catch (std::exception const& e) {
      logging::error(logging::high)
        << "multiplexing: could not backup memory queue of '" << _name
        << "': " << e.what();
    }
  }
  _events.clear();
  _events_size = 0;
  return ;
}

/**
 *  Get event from retention file. Warning: lock _mutex before using
 *  this function.
 *
 *  @param[out] event  Last event available. Null if none is available.
 */
void muxer::_get_event_from_file(misc::shared_ptr<io::data>& event) {
  event.clear();
  // If file exist, try to get the last event.
  if (_file.get()) {
    try {
      do {
        _file->read(event);
      } while (event.isNull());
    }
    catch (io::exceptions::shutdown const& e) {
      // The file end was reach.
      (void)e;
      _file.reset();
    }
  }
  return ;
}

/**
 *  Get memory file path.
 *
 *  @return Path to the memory file.
 */
std::string muxer::_memory_file() const {
  return (memory_file(_name));
}

/**
 *  Push event to queue.
 *
 *  @param[in] event  New event.
 */
void muxer::_push_to_queue(misc::shared_ptr<io::data> const& event) {
  bool pos_has_no_more_to_read(_pos == _events.end());
  _events.push_back(event);
  ++_events_size;
  if (pos_has_no_more_to_read) {
    _pos = --_events.end();
    _cv.wakeOne();
  }
  return ;
}

/**
 *  Get queue file path.
 *
 *  @return Path to the queue file.
 */
std::string muxer::_queue_file() const {
  return (queue_file(_name));
}
<|endoftext|>


<commit_before>#include <stdio.h>

#include "HalideRuntime.h"
#include "HalideBuffer.h"
#include <assert.h>
#include <string.h>

#include "cxx_mangling.h"
#if WITH_PTX
#include "cxx_mangling_gpu.h"
#endif

using namespace Halide::Runtime;

int32_t extract_value_global(int32_t *arg) {
    return *arg;
}

namespace HalideTest {

int32_t extract_value_ns(const int32_t *arg) {
    return *arg;
}

}

namespace my_namespace {
class my_class {public: int foo;};
namespace my_subnamespace {
struct my_struct {int foo;};
}
}
union my_union {
    float a;
    int b;
};

int main(int argc, char **argv) {
    Buffer<uint8_t> input(100);

    for (int32_t i = 0; i < 100; i++) {
        input(i) = i;
    }

    Buffer<double> result(100);

    const halide_filter_metadata_t *m = HalideTest::cxx_mangling_metadata();
    assert(m != NULL);
    printf("Name is: %s\n", m->name);
    assert(strcmp(m->name, "cxx_mangling") == 0);

    int ptr_arg = 42;
    int *int_ptr = &ptr_arg;
    const int *const_int_ptr = &ptr_arg;
    void *void_ptr = nullptr;
    const void *const_void_ptr = nullptr;
    std::string *string_ptr = nullptr;
    const std::string *const_string_ptr = nullptr;

#if WITH_PTX
    // Don't bother calling this (we haven't linked in the CUDA support it needs),
    // just force a reference to ensure it is linked in.
    int (*f)(halide_buffer_t *,
             int8_t, uint8_t,
             int16_t, uint16_t,
             int32_t, uint32_t,
             int64_t, uint64_t,
             bool,
             float, double,
             int32_t *, int32_t const *,
             void *, void const *,
             void *, void const *,
             halide_buffer_t *) = HalideTest::cxx_mangling_gpu;

    printf("HalideTest::cxx_mangling is at: %p\n", (void*) f);
#endif

    my_namespace::my_class mc;
    my_namespace::my_subnamespace::my_struct ms;
    my_union mu;

    int r = HalideTest::cxx_mangling(input, -1, 0xff, -1, 0xffff, -1, 0xffffffff,
                                     -1, 0xffffffffffffffffLL, true, 42.0, 4239.0f,
                                     int_ptr, const_int_ptr, void_ptr, const_void_ptr,
                                     string_ptr, const_string_ptr,
                                     &mc, &ms, &mu, result);
    if (r != 0) {
        fprintf(stderr, "Failure!\n");
        exit(1);
    }
    printf("Success!\n");
    return 0;
}
<commit_msg>Fix cxx_mangling_aottest for WITH_PTX case<commit_after>#include <stdio.h>

#include "HalideRuntime.h"
#include "HalideBuffer.h"
#include <assert.h>
#include <string.h>

#include "cxx_mangling.h"
#if WITH_PTX
#include "cxx_mangling_gpu.h"
#endif

using namespace Halide::Runtime;

int32_t extract_value_global(int32_t *arg) {
    return *arg;
}

namespace HalideTest {

int32_t extract_value_ns(const int32_t *arg) {
    return *arg;
}

}

namespace my_namespace {
class my_class {public: int foo;};
namespace my_subnamespace {
struct my_struct {int foo;};
}
}
union my_union {
    float a;
    int b;
};

int main(int argc, char **argv) {
    Buffer<uint8_t> input(100);

    for (int32_t i = 0; i < 100; i++) {
        input(i) = i;
    }

    Buffer<double> result(100);

    const halide_filter_metadata_t *m = HalideTest::cxx_mangling_metadata();
    assert(m != NULL);
    printf("Name is: %s\n", m->name);
    assert(strcmp(m->name, "cxx_mangling") == 0);

    int ptr_arg = 42;
    int *int_ptr = &ptr_arg;
    const int *const_int_ptr = &ptr_arg;
    void *void_ptr = nullptr;
    const void *const_void_ptr = nullptr;
    std::string *string_ptr = nullptr;
    const std::string *const_string_ptr = nullptr;

#if WITH_PTX
    // Don't bother calling this (we haven't linked in the CUDA support it needs),
    // just force a reference to ensure it is linked in.
    int (*f)(halide_buffer_t *,
             int8_t, uint8_t,
             int16_t, uint16_t,
             int32_t, uint32_t,
             int64_t, uint64_t,
             bool,
             float, double,
             int32_t *, int32_t const *,
             void *, void const *,
             void *, void const *,
             ::my_namespace::my_class const *,
             struct ::my_namespace::my_subnamespace::my_struct const *,
             my_union const *,
             halide_buffer_t *) = HalideTest::cxx_mangling_gpu;

    printf("HalideTest::cxx_mangling is at: %p\n", (void*) f);
#endif

    my_namespace::my_class mc;
    my_namespace::my_subnamespace::my_struct ms;
    my_union mu;

    int r = HalideTest::cxx_mangling(input, -1, 0xff, -1, 0xffff, -1, 0xffffffff,
                                     -1, 0xffffffffffffffffLL, true, 42.0, 4239.0f,
                                     int_ptr, const_int_ptr, void_ptr, const_void_ptr,
                                     string_ptr, const_string_ptr,
                                     &mc, &ms, &mu, result);
    if (r != 0) {
        fprintf(stderr, "Failure!\n");
        exit(1);
    }
    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>/** \file    normalise_marc_contents.cc
 *  \brief   Replace variant entries in MARC subfields w/ a standardised form.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2018 Library of the University of Tübingen

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

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <iostream>
#include <map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cstring>
#include "Compiler.h"
#include "IniFile.h"
#include "MARC.h"
#include "StringUtil.h"
#include "TextUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " marc_input marc_output\n";
    std::exit(EXIT_FAILURE);
}

typedef std::map<std::string, std::string> VariantsToCanonicalNameMap;

std::string NormaliseSubfieldContents(std::string subfield_contents) {
    TextUtil::UTF8ToLower(&subfield_contents);
    return TextUtil::CollapseAndTrimWhitespace(&subfield_contents);
}

void LoadTagAndSubfieldCodesGroupsFromGlobalSection(const IniFile &ini_file,
                                                    std::map<std::string, std::vector<std::string>> * const subfields_name_to_subfields_map)
{
    const IniFile::Section &global_section(ini_file.getSection(""));

    for (const auto &entry_and_value : global_section) {
        if (unlikely(subfields_name_to_subfields_map->find(entry_and_value.first) != subfields_name_to_subfields_map->cend()))
            LOG_ERROR("duplicate subfields name \"" + entry_and_value.first + "\"!");
        if (unlikely(entry_and_value.second.empty()))
            LOG_ERROR("missing subfields spec for \"" + entry_and_value.first + "\"!");

        std::vector<std::string> tags_and_subfield_codes;
        StringUtil::Split(entry_and_value.second, ':', &tags_and_subfield_codes);
        for (const auto &tag_and_subfield_code : tags_and_subfield_codes) {
            if (unlikely(tag_and_subfield_code.length() != MARC::Record::TAG_LENGTH + 1))
                LOG_ERROR("bad subfields spec for \"" + entry_and_value.first + "\"!");
        }

        (*subfields_name_to_subfields_map)[entry_and_value.first] = tags_and_subfield_codes;
    }
}

void InsertVariantsIntoMap(const std::vector<std::string> &subfield_specs, const std::unordered_set<std::string> &variants,
                           const std::string &canonical_name, std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> * const maps)
{
    for (const auto &subfield_spec : subfield_specs) {
        auto subfield_spec_and_replacement_map(
            std::find_if(maps->begin(), maps->end(),
                         [&subfield_spec](std::pair<std::string, VariantsToCanonicalNameMap> &subfield_spec_and_replacement_map)
                             { return subfield_spec == subfield_spec_and_replacement_map.first; }));
        if (subfield_spec_and_replacement_map == maps->end()) {
            maps->emplace_back(subfield_spec, VariantsToCanonicalNameMap{});
            subfield_spec_and_replacement_map = maps->end() - 1;
        }

        for (const auto &variant : variants)
            subfield_spec_and_replacement_map->second.insert(std::make_pair(variant, canonical_name));
    }
}

// The structure of the config file is as follows:
// In the gobal section at the top there must be one or more string entries which have values that consist of colon-separated
// subfield references, e.g.
//              authors    = "100a:700a:710a"
//              publishers = "400d:422d"
//
// The named sections have the following structure:
//   The name of the section itself is the canonical name, i.e. what we want to use to replace the variants.
//   There must be one entry named "subfields" whose value is one of the entries in the global section.
//   All other entries must have names starting with "variant".  These variants will be replaced with the
//   canonical name if found in a relevent subfield.  An example might look like
//
//   [Fred & Johnson]
//   subfields = "publishers"
//   variant1 = "Fred and Johnson"
//   variant2 = "F. & J."
//
void LoadConfigFile(std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> * const maps) {
    const IniFile ini_file("/usr/local/var/lib/tuelib/normalise_marc_contents.conf");

    std::map<std::string, std::vector<std::string>> subfields_name_to_subfields_map;
    LoadTagAndSubfieldCodesGroupsFromGlobalSection(ini_file, &subfields_name_to_subfields_map);

    for (const auto &section : ini_file) {
        if (section.first.empty())
            continue;

        const std::string canonical_name(section.first);
        const std::vector<std::string> *subfield_specs(nullptr);
        std::unordered_set<std::string> variants;
        for (const auto &entry_and_value : section.second) {
            if (entry_and_value.first == "subfields") {
                const auto subfields_name_and_specs(subfields_name_to_subfields_map.find(entry_and_value.second));
                if (unlikely(subfields_name_and_specs == subfields_name_to_subfields_map.cend()))
                    LOG_ERROR("unknown \"subfields\": \"" + entry_and_value.second + "\"!");
                subfield_specs = &(subfields_name_and_specs->second);
            } else {
                if (unlikely(not StringUtil::StartsWith(entry_and_value.first, "variant")))
                    LOG_ERROR("unknown entry \"" + entry_and_value.first + "\" entry in section \"" + section.first + "\"!");
                variants.emplace(NormaliseSubfieldContents(entry_and_value.second));
            }
        }

        if (unlikely(variants.empty()))
            LOG_ERROR("missing variants entries in the \"" + section.first + "\" section!");
        if (unlikely(subfield_specs == nullptr))
            LOG_ERROR("missing \"subfields\" entry for the \"" + section.first + "\" section!");
        InsertVariantsIntoMap(*subfield_specs, variants, canonical_name, maps);
    }

    // Sort into ascending order of subfield specs:
    std::sort(maps->begin(), maps->end(),
              [](const std::pair<std::string, VariantsToCanonicalNameMap> &a, const std::pair<std::string, VariantsToCanonicalNameMap> &b)
                  { return a.first < b.first; });

    LOG_INFO("loaded " + std::to_string(maps->size()) + " substitution maps.");
}

void ProcessRecords(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                    const std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> &maps)
{
    unsigned total_count(0), modified_count(0);
    while (MARC::Record record = marc_reader->read()) {
        bool replaced_at_least_one_field(false);
        ++total_count;

        auto subfield_spec_and_replacement_map(maps.cbegin());
        for (auto &field : record) {
            while (subfield_spec_and_replacement_map != maps.cend() and subfield_spec_and_replacement_map->first < field.getTag().toString())
                ++subfield_spec_and_replacement_map;
            if (subfield_spec_and_replacement_map == maps.cend())
                break;

            if (subfield_spec_and_replacement_map->first.substr(0, MARC::Record::TAG_LENGTH) == field.getTag().toString()) {
                const char SUBFIELD_CODE(subfield_spec_and_replacement_map->first[MARC::Record::TAG_LENGTH]);
                MARC::Subfields subfields(field.getSubfields());

                bool replaced_at_least_one_subfield(false);
                for (auto &subfield : subfields) {
                    if (subfield.code_ == SUBFIELD_CODE) {
                        const std::string normalised_subfield_contents(NormaliseSubfieldContents(subfield.value_));
                        auto variant_and_canonical_value(subfield_spec_and_replacement_map->second.find(normalised_subfield_contents));
                        if (variant_and_canonical_value != subfield_spec_and_replacement_map->second.cend()) {
                            subfield.value_ = variant_and_canonical_value->second;
                            replaced_at_least_one_subfield = true;
                        }
                    }
                }

                if (replaced_at_least_one_subfield) {
                    field.setContents(subfields, field.getIndicator1(), field.getIndicator2());
                    replaced_at_least_one_field = true;
                }
            }
        }

        if (replaced_at_least_one_field)
            ++modified_count;

        marc_writer->write(record);
    }
    LOG_INFO("Processed " + std::to_string(total_count) + " records and modified " + std::to_string(modified_count) + " record(s).");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    ::progname = argv[0];

    if (argc != 3)
        Usage();

    std::unique_ptr<MARC::Reader> marc_reader(MARC::Reader::Factory(argv[1]));
    std::unique_ptr<MARC::Writer> marc_writer(MARC::Writer::Factory(argv[2]));

    std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> maps;
    LoadConfigFile(&maps);
    ProcessRecords(marc_reader.get(), marc_writer.get(), maps);

    return EXIT_SUCCESS;
}
<commit_msg>Address shadow error in lamda<commit_after>/** \file    normalise_marc_contents.cc
 *  \brief   Replace variant entries in MARC subfields w/ a standardised form.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2018 Library of the University of Tübingen

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

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <iostream>
#include <map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cstring>
#include "Compiler.h"
#include "IniFile.h"
#include "MARC.h"
#include "StringUtil.h"
#include "TextUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " marc_input marc_output\n";
    std::exit(EXIT_FAILURE);
}

typedef std::map<std::string, std::string> VariantsToCanonicalNameMap;

std::string NormaliseSubfieldContents(std::string subfield_contents) {
    TextUtil::UTF8ToLower(&subfield_contents);
    return TextUtil::CollapseAndTrimWhitespace(&subfield_contents);
}

void LoadTagAndSubfieldCodesGroupsFromGlobalSection(const IniFile &ini_file,
                                                    std::map<std::string, std::vector<std::string>> * const subfields_name_to_subfields_map)
{
    const IniFile::Section &global_section(ini_file.getSection(""));

    for (const auto &entry_and_value : global_section) {
        if (unlikely(subfields_name_to_subfields_map->find(entry_and_value.first) != subfields_name_to_subfields_map->cend()))
            LOG_ERROR("duplicate subfields name \"" + entry_and_value.first + "\"!");
        if (unlikely(entry_and_value.second.empty()))
            LOG_ERROR("missing subfields spec for \"" + entry_and_value.first + "\"!");

        std::vector<std::string> tags_and_subfield_codes;
        StringUtil::Split(entry_and_value.second, ':', &tags_and_subfield_codes);
        for (const auto &tag_and_subfield_code : tags_and_subfield_codes) {
            if (unlikely(tag_and_subfield_code.length() != MARC::Record::TAG_LENGTH + 1))
                LOG_ERROR("bad subfields spec for \"" + entry_and_value.first + "\"!");
        }

        (*subfields_name_to_subfields_map)[entry_and_value.first] = tags_and_subfield_codes;
    }
}

void InsertVariantsIntoMap(const std::vector<std::string> &subfield_specs, const std::unordered_set<std::string> &variants,
                           const std::string &canonical_name, std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> * const maps)
{
    for (const auto &subfield_spec : subfield_specs) {
        auto subfield_spec_and_replacement_map(
            std::find_if(maps->begin(), maps->end(),
                         [&subfield_spec](std::pair<std::string, VariantsToCanonicalNameMap> &subfield_spec_and_replacement_map1)
                             { return subfield_spec == subfield_spec_and_replacement_map1.first; }));
        if (subfield_spec_and_replacement_map == maps->end()) {
            maps->emplace_back(subfield_spec, VariantsToCanonicalNameMap{});
            subfield_spec_and_replacement_map = maps->end() - 1;
        }

        for (const auto &variant : variants)
            subfield_spec_and_replacement_map->second.insert(std::make_pair(variant, canonical_name));
    }
}

// The structure of the config file is as follows:
// In the gobal section at the top there must be one or more string entries which have values that consist of colon-separated
// subfield references, e.g.
//              authors    = "100a:700a:710a"
//              publishers = "400d:422d"
//
// The named sections have the following structure:
//   The name of the section itself is the canonical name, i.e. what we want to use to replace the variants.
//   There must be one entry named "subfields" whose value is one of the entries in the global section.
//   All other entries must have names starting with "variant".  These variants will be replaced with the
//   canonical name if found in a relevent subfield.  An example might look like
//
//   [Fred & Johnson]
//   subfields = "publishers"
//   variant1 = "Fred and Johnson"
//   variant2 = "F. & J."
//
void LoadConfigFile(std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> * const maps) {
    const IniFile ini_file("/usr/local/var/lib/tuelib/normalise_marc_contents.conf");

    std::map<std::string, std::vector<std::string>> subfields_name_to_subfields_map;
    LoadTagAndSubfieldCodesGroupsFromGlobalSection(ini_file, &subfields_name_to_subfields_map);

    for (const auto &section : ini_file) {
        if (section.first.empty())
            continue;

        const std::string canonical_name(section.first);
        const std::vector<std::string> *subfield_specs(nullptr);
        std::unordered_set<std::string> variants;
        for (const auto &entry_and_value : section.second) {
            if (entry_and_value.first == "subfields") {
                const auto subfields_name_and_specs(subfields_name_to_subfields_map.find(entry_and_value.second));
                if (unlikely(subfields_name_and_specs == subfields_name_to_subfields_map.cend()))
                    LOG_ERROR("unknown \"subfields\": \"" + entry_and_value.second + "\"!");
                subfield_specs = &(subfields_name_and_specs->second);
            } else {
                if (unlikely(not StringUtil::StartsWith(entry_and_value.first, "variant")))
                    LOG_ERROR("unknown entry \"" + entry_and_value.first + "\" entry in section \"" + section.first + "\"!");
                variants.emplace(NormaliseSubfieldContents(entry_and_value.second));
            }
        }

        if (unlikely(variants.empty()))
            LOG_ERROR("missing variants entries in the \"" + section.first + "\" section!");
        if (unlikely(subfield_specs == nullptr))
            LOG_ERROR("missing \"subfields\" entry for the \"" + section.first + "\" section!");
        InsertVariantsIntoMap(*subfield_specs, variants, canonical_name, maps);
    }

    // Sort into ascending order of subfield specs:
    std::sort(maps->begin(), maps->end(),
              [](const std::pair<std::string, VariantsToCanonicalNameMap> &a, const std::pair<std::string, VariantsToCanonicalNameMap> &b)
                  { return a.first < b.first; });

    LOG_INFO("loaded " + std::to_string(maps->size()) + " substitution maps.");
}

void ProcessRecords(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                    const std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> &maps)
{
    unsigned total_count(0), modified_count(0);
    while (MARC::Record record = marc_reader->read()) {
        bool replaced_at_least_one_field(false);
        ++total_count;

        auto subfield_spec_and_replacement_map(maps.cbegin());
        for (auto &field : record) {
            while (subfield_spec_and_replacement_map != maps.cend() and subfield_spec_and_replacement_map->first < field.getTag().toString())
                ++subfield_spec_and_replacement_map;
            if (subfield_spec_and_replacement_map == maps.cend())
                break;

            if (subfield_spec_and_replacement_map->first.substr(0, MARC::Record::TAG_LENGTH) == field.getTag().toString()) {
                const char SUBFIELD_CODE(subfield_spec_and_replacement_map->first[MARC::Record::TAG_LENGTH]);
                MARC::Subfields subfields(field.getSubfields());

                bool replaced_at_least_one_subfield(false);
                for (auto &subfield : subfields) {
                    if (subfield.code_ == SUBFIELD_CODE) {
                        const std::string normalised_subfield_contents(NormaliseSubfieldContents(subfield.value_));
                        auto variant_and_canonical_value(subfield_spec_and_replacement_map->second.find(normalised_subfield_contents));
                        if (variant_and_canonical_value != subfield_spec_and_replacement_map->second.cend()) {
                            subfield.value_ = variant_and_canonical_value->second;
                            replaced_at_least_one_subfield = true;
                        }
                    }
                }

                if (replaced_at_least_one_subfield) {
                    field.setContents(subfields, field.getIndicator1(), field.getIndicator2());
                    replaced_at_least_one_field = true;
                }
            }
        }

        if (replaced_at_least_one_field)
            ++modified_count;

        marc_writer->write(record);
    }
    LOG_INFO("Processed " + std::to_string(total_count) + " records and modified " + std::to_string(modified_count) + " record(s).");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    ::progname = argv[0];

    if (argc != 3)
        Usage();

    std::unique_ptr<MARC::Reader> marc_reader(MARC::Reader::Factory(argv[1]));
    std::unique_ptr<MARC::Writer> marc_writer(MARC::Writer::Factory(argv[2]));

    std::vector<std::pair<std::string, VariantsToCanonicalNameMap>> maps;
    LoadConfigFile(&maps);
    ProcessRecords(marc_reader.get(), marc_writer.get(), maps);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

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

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file shhrpc.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <test/TestHelper.h>
#include <test/libweb3jsonrpc/webthreestubclient.h>
#include <libethcore/KeyManager.h>
#include <libp2p/Common.h>
#include <libwhisper/WhisperHost.h>

using namespace std;
using namespace dev;
using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;

WebThreeDirect* web3;
unique_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<WebThreeStubClient> jsonrpcClient;

string fromAscii(string _s) { return toHex(asBytes(_s), 2, HexPrefix::Add); }

struct Setup
{
	Setup()
	{
		static bool setup = false;
		if (!setup)
		{
			setup = true;
			NetworkPreferences nprefs(std::string(), 30333, false);
			web3 = new WebThreeDirect("shhrpc-web3", "", WithExisting::Trust, {"eth", "shh"}, nprefs);
			web3->setIdealPeerCount(1);
			web3->ethereum()->setForceMining(false);
			auto server = new jsonrpc::HttpServer(8080);
			vector<KeyPair> v;
			KeyManager keyMan;
			TrivialGasPricer gp;
			jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(*server, *web3, nullptr, v, keyMan, gp));
			jsonrpcServer->setIdentities({});
			jsonrpcServer->StartListening();
			auto client = new jsonrpc::HttpClient("http://localhost:8080");
			jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(*client));
		}
	}
};

BOOST_FIXTURE_TEST_SUITE(shhrpc, Setup)

BOOST_AUTO_TEST_CASE(web3face)
{
	cnote << "Testing web3 interface...";

	web3->startNetwork();
	unsigned const step = 10;
	for (unsigned i = 0; i < 3000 && !web3->haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(web3->haveNetwork());

	uint16_t const port2 = 30334;
	NetworkPreferences prefs("127.0.0.1", port2, false);
	string const version = "shhrpc-host2";
	Host host2(version, prefs);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();

	for (unsigned i = 0; i < 3000 && !host2.haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());

	web3->requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);
	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);

	vector<PeerSessionInfo> vpeers = web3->peers();
	BOOST_REQUIRE(!vpeers.empty());
	PeerSessionInfo const& peer = vpeers.back();
	BOOST_REQUIRE_EQUAL(peer.id, host2.id());
	BOOST_REQUIRE_EQUAL(peer.port, port2);
	BOOST_REQUIRE_EQUAL(peer.clientVersion, version);

	web3->stopNetwork();

	for (unsigned i = 0; i < 3000 && web3->haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(!web3->peerCount());
	BOOST_REQUIRE(!host2.peerCount());
}

BOOST_AUTO_TEST_CASE(send)
{
	cnote << "Testing send functionality...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 10;
	unsigned const step = 10;
	uint16_t port2 = 30311;
	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		auto w = whost2->installWatch(BuildTopicMask("odd"));
		ready = true;
		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: whost2->checkWatch(w))
			{
				Message msg = whost2->envelope(i).open(whost2->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	web3->requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	for (unsigned i = 0; i < 2000 && !ready; i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(ready);

	KeyPair us = KeyPair::create();
	for (int i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	auto messages = web3->whisper()->all();
	BOOST_REQUIRE_EQUAL(messages.size(), messageCount);

	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>web3 test complete<commit_after>/*
	This file is part of cpp-ethereum.

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

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file shhrpc.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <test/TestHelper.h>
#include <test/libweb3jsonrpc/webthreestubclient.h>
#include <libethcore/KeyManager.h>
#include <libp2p/Common.h>
#include <libwhisper/WhisperHost.h>

using namespace std;
using namespace dev;
using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;

WebThreeDirect* web3;
unique_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<WebThreeStubClient> jsonrpcClient;
static uint16_t const web3port = 30333;

struct Setup
{
	Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = true;

		static bool setup = false;
		if (!setup)
		{
			setup = true;
			NetworkPreferences nprefs(std::string(), web3port, false);
			web3 = new WebThreeDirect("shhrpc-web3", "", WithExisting::Trust, {"eth", "shh"}, nprefs);
			web3->setIdealPeerCount(1);
			web3->ethereum()->setForceMining(false);
			auto server = new jsonrpc::HttpServer(8080);
			vector<KeyPair> v;
			KeyManager keyMan;
			TrivialGasPricer gp;
			jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(*server, *web3, nullptr, v, keyMan, gp));
			jsonrpcServer->setIdentities({});
			jsonrpcServer->StartListening();
			auto client = new jsonrpc::HttpClient("http://localhost:8080");
			jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(*client));
		}
	}

	~Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = false;
	}
};

BOOST_FIXTURE_TEST_SUITE(shhrpc, Setup)

BOOST_AUTO_TEST_CASE(basic)
{
	cnote << "Testing web3 basic functionality...";

	web3->startNetwork();
	unsigned const step = 10;
	for (unsigned i = 0; i < 3000 && !web3->haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(web3->haveNetwork());

	uint16_t const port2 = 30334;
	NetworkPreferences prefs2("127.0.0.1", port2, false);
	string const version2 = "shhrpc-host2";
	Host host2(version2, prefs2);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();

	for (unsigned i = 0; i < 3000 && !host2.haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());

	web3->addNode(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	vector<PeerSessionInfo> vpeers = web3->peers();
	BOOST_REQUIRE(!vpeers.empty());
	PeerSessionInfo const& peer = vpeers.back();
	BOOST_REQUIRE_EQUAL(peer.id, host2.id());
	BOOST_REQUIRE_EQUAL(peer.port, port2);
	BOOST_REQUIRE_EQUAL(peer.clientVersion, version2);

	web3->stopNetwork();

	for (unsigned i = 0; i < 3000 && (web3->haveNetwork() || host2.haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(!web3->peerCount());
	BOOST_REQUIRE(!host2.peerCount());
}

BOOST_AUTO_TEST_CASE(send)
{
	cnote << "Testing web3 send...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 10;
	unsigned const step = 10;
	uint16_t port2 = 30337;

	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = whost2->installWatch(BuildTopicMask("odd"));
		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: whost2->checkWatch(w))
			{
				Message msg = whost2->envelope(i).open(whost2->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	web3->requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (int i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	auto messages = web3->whisper()->all();
	BOOST_REQUIRE_EQUAL(messages.size(), messageCount);

	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
}

BOOST_AUTO_TEST_CASE(receive)
{
	cnote << "Testing web3 receive...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 6;
	unsigned const step = 10;
	uint16_t port2 = 30338;
	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = web3->whisper()->installWatch(BuildTopicMask("odd"));

		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: web3->whisper()->checkWatch(w))
			{
				Message msg = web3->whisper()->envelope(i).open(web3->whisper()->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	host2.addNode(web3->id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), web3port, web3port));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (int i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 27 + 125);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <ir/Zambezi/buffer/AttrScoreBufferMaps.hpp>

NS_IZENELIB_IR_BEGIN

namespace Zambezi
{

AttrScoreBufferMaps::AttrScoreBufferMaps(uint32_t initialSize)
    : capacity(initialSize)
    , buffer(initialSize)
    , tailPointer(initialSize, UNDEFINED_POINTER)
{
}

AttrScoreBufferMaps::~AttrScoreBufferMaps()
{
}

void AttrScoreBufferMaps::save(std::ostream& ostr) const
{
    ostr.write((const char*)&capacity, sizeof(capacity));

    size_t termNum;
    for (termNum = 0; termNum < capacity; ++termNum)
    {
        if (!buffer[termNum])
        {
            uint32_t capacity = 0;
            ostr.write((const char*)&capacity, sizeof(uint32_t));
            break;
        }

        uint32_t capacity = buffer[termNum]->capacity();
        ostr.write((const char*)&capacity, sizeof(uint32_t));

        uint32_t size = buffer[termNum]->size();
        ostr.write((const char*)&size, sizeof(uint32_t));

        ostr.write((const char*)&(*buffer[termNum])[0], sizeof(ElemType) * size);
    }

    ostr.write((const char*)&tailPointer[0], sizeof(size_t) * termNum);
}

void AttrScoreBufferMaps::load(std::istream& istr)
{
    istr.read((char*)&capacity, sizeof(capacity));
    buffer.resize(capacity);

    size_t termNum;
    for (termNum = 0; termNum < capacity; ++termNum)
    {
        uint32_t capacity = 0;
        istr.read((char*)&capacity, sizeof(uint32_t));

        if (capacity == 0) break;

        resizePosting(termNum, capacity);

        uint32_t size = 0;
        istr.read((char*)&size, sizeof(uint32_t));
        buffer[termNum]->resize(size);

        istr.read((char*)&(*buffer[termNum])[0], sizeof(uint32_t) * size);
    }

    tailPointer.resize(capacity, UNDEFINED_POINTER);
    istr.read((char*)&tailPointer[0], sizeof(size_t) * termNum);
}

void AttrScoreBufferMaps::expand(uint32_t newSize)
{
    if (newSize <= capacity) return;

    if (capacity == 0)
    {
        capacity = newSize;
    }
    else
    {
        while (newSize > capacity)
        {
            capacity *= 2;
        }
    }

    buffer.resize(capacity);
    tailPointer.resize(capacity, UNDEFINED_POINTER);
}

uint32_t AttrScoreBufferMaps::nextIndex(uint32_t pos, uint32_t minLength) const
{
    do
    {
        if (++pos >= capacity)
        {
            return UNDEFINED_OFFSET;
        }
    }
    while (buffer[pos]->empty() || buffer[pos]->capacity() <= minLength);

    return pos;
}

boost::shared_ptr<AttrScoreBufferMaps::PostingType> AttrScoreBufferMaps::getPosting(uint32_t id) const
{
    boost::atomic_flag& flag = flags[id];
    while (flag.test_and_set());
    boost::shared_ptr<PostingType> res(buffer[id]);
    flag.clear();

    return res;
}

void AttrScoreBufferMaps::resizePosting(uint32_t id, size_t new_size)
{
    boost::shared_ptr<PostingType>& old_buffer = buffer[id];
    boost::shared_ptr<PostingType> new_buffer(new PostingType);
    new_buffer->reserve(new_size);
    new_buffer->assign(old_buffer->begin(), old_buffer->end());

    boost::atomic_flag& flag = flags[id];
    while (flag.test_and_set());
    old_buffer.swap(new_buffer);
    flag.clear();
}

}

NS_IZENELIB_IR_END
<commit_msg>fix init<commit_after>#include <ir/Zambezi/buffer/AttrScoreBufferMaps.hpp>

NS_IZENELIB_IR_BEGIN

namespace Zambezi
{

AttrScoreBufferMaps::AttrScoreBufferMaps(uint32_t initialSize)
    : capacity(initialSize)
    , flags(new boost::atomic_flag[initialSize])
    , buffer(initialSize)
    , tailPointer(initialSize, UNDEFINED_POINTER)
{
}

AttrScoreBufferMaps::~AttrScoreBufferMaps()
{
}

void AttrScoreBufferMaps::save(std::ostream& ostr) const
{
    ostr.write((const char*)&capacity, sizeof(capacity));

    size_t termNum;
    for (termNum = 0; termNum < capacity; ++termNum)
    {
        if (!buffer[termNum])
        {
            uint32_t capacity = 0;
            ostr.write((const char*)&capacity, sizeof(uint32_t));
            break;
        }

        uint32_t capacity = buffer[termNum]->capacity();
        ostr.write((const char*)&capacity, sizeof(uint32_t));

        uint32_t size = buffer[termNum]->size();
        ostr.write((const char*)&size, sizeof(uint32_t));

        ostr.write((const char*)&(*buffer[termNum])[0], sizeof(ElemType) * size);
    }

    ostr.write((const char*)&tailPointer[0], sizeof(size_t) * termNum);
}

void AttrScoreBufferMaps::load(std::istream& istr)
{
    istr.read((char*)&capacity, sizeof(capacity));
    flags.reset(new boost::atomic_flag[capacity]);
    buffer.resize(capacity);

    size_t termNum;
    for (termNum = 0; termNum < capacity; ++termNum)
    {
        uint32_t capacity = 0;
        istr.read((char*)&capacity, sizeof(uint32_t));

        if (capacity == 0) break;

        resizePosting(termNum, capacity);

        uint32_t size = 0;
        istr.read((char*)&size, sizeof(uint32_t));
        buffer[termNum]->resize(size);

        istr.read((char*)&(*buffer[termNum])[0], sizeof(uint32_t) * size);
    }

    tailPointer.resize(capacity, UNDEFINED_POINTER);
    istr.read((char*)&tailPointer[0], sizeof(size_t) * termNum);
}

void AttrScoreBufferMaps::expand(uint32_t newSize)
{
    if (newSize <= capacity) return;

    if (capacity == 0)
    {
        capacity = newSize;
    }
    else
    {
        while (newSize > capacity)
        {
            capacity *= 2;
        }
    }

    buffer.resize(capacity);
    tailPointer.resize(capacity, UNDEFINED_POINTER);
}

uint32_t AttrScoreBufferMaps::nextIndex(uint32_t pos, uint32_t minLength) const
{
    do
    {
        if (++pos >= capacity)
        {
            return UNDEFINED_OFFSET;
        }
    }
    while (buffer[pos]->empty() || buffer[pos]->capacity() <= minLength);

    return pos;
}

boost::shared_ptr<AttrScoreBufferMaps::PostingType> AttrScoreBufferMaps::getPosting(uint32_t id) const
{
    boost::atomic_flag& flag = flags[id];
    while (flag.test_and_set());
    boost::shared_ptr<PostingType> res(buffer[id]);
    flag.clear();

    return res;
}

void AttrScoreBufferMaps::resizePosting(uint32_t id, size_t new_size)
{
    boost::shared_ptr<PostingType>& old_buffer = buffer[id];
    boost::shared_ptr<PostingType> new_buffer(new PostingType);
    new_buffer->reserve(new_size);
    new_buffer->assign(old_buffer->begin(), old_buffer->end());

    boost::atomic_flag& flag = flags[id];
    while (flag.test_and_set());
    old_buffer.swap(new_buffer);
    flag.clear();
}

}

NS_IZENELIB_IR_END
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tools.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 13:23:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_TOOLS_HXX
#define _CPPCANVAS_TOOLS_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif

namespace com { namespace sun { namespace star { namespace rendering
{
    class  XGraphicDevice;
} } } }

namespace cppcanvas
{
    namespace tools
    {
        ::com::sun::star::uno::Sequence< double >
            intSRGBAToDoubleSequence( const ::com::sun::star::uno::Reference<
                                              ::com::sun::star::rendering::XGraphicDevice >&,
                                      Color::IntSRGBA );

        Color::IntSRGBA doubleSequenceToIntSRGBA( const ::com::sun::star::uno::Reference<
                                                          ::com::sun::star::rendering::XGraphicDevice >&    rDevice,
                                                  const ::com::sun::star::uno::Sequence< double >&              rColor  );
    }
}

#endif /* _CPPCANVAS_TOOLS_HXX */
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.20); FILE MERGED 2005/09/05 18:40:57 rt 1.3.20.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tools.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:17:26 $
 *
 *  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 _CPPCANVAS_TOOLS_HXX
#define _CPPCANVAS_TOOLS_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif

namespace com { namespace sun { namespace star { namespace rendering
{
    class  XGraphicDevice;
} } } }

namespace cppcanvas
{
    namespace tools
    {
        ::com::sun::star::uno::Sequence< double >
            intSRGBAToDoubleSequence( const ::com::sun::star::uno::Reference<
                                              ::com::sun::star::rendering::XGraphicDevice >&,
                                      Color::IntSRGBA );

        Color::IntSRGBA doubleSequenceToIntSRGBA( const ::com::sun::star::uno::Reference<
                                                          ::com::sun::star::rendering::XGraphicDevice >&    rDevice,
                                                  const ::com::sun::star::uno::Sequence< double >&              rColor  );
    }
}

#endif /* _CPPCANVAS_TOOLS_HXX */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: loadmodule.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-10-15 12:19:51 $
 *
 *  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 2007 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cppu.hxx"

#include "sal/config.h"

#include "osl/module.h"
#include "rtl/string.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.hxx"

#include "loadmodule.hxx"

namespace cppu { namespace detail {

::oslModule loadModule(rtl::OUString const & name) {
    rtl::OUStringBuffer b;
#if defined SAL_DLLPREFIX
    b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX));
#endif
    b.append(name);
    b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION));
    return ::osl_loadModuleRelative(
        reinterpret_cast< oslGenericFunction >(&loadModule),
        b.makeStringAndClear().pData,
        SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY);
}

} }
<commit_msg>INTEGRATION: CWS changefileheader (1.2.18); FILE MERGED 2008/03/31 07:23:22 rt 1.2.18.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: loadmodule.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cppu.hxx"

#include "sal/config.h"

#include "osl/module.h"
#include "rtl/string.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.hxx"

#include "loadmodule.hxx"

namespace cppu { namespace detail {

::oslModule loadModule(rtl::OUString const & name) {
    rtl::OUStringBuffer b;
#if defined SAL_DLLPREFIX
    b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX));
#endif
    b.append(name);
    b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION));
    return ::osl_loadModuleRelative(
        reinterpret_cast< oslGenericFunction >(&loadModule),
        b.makeStringAndClear().pData,
        SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY);
}

} }
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMAirframeComponent.h"
#include "ArduCopterFirmwarePlugin.h"
#include "ParameterManager.h"

const char* APMAirframeComponent::_oldFrameParam = "FRAME";
const char* APMAirframeComponent::_newFrameParam = "FRAME_CLASS";

APMAirframeComponent::APMAirframeComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
    : VehicleComponent(vehicle, autopilot, parent)
    , _requiresFrameSetup(false)
    , _name(tr("Airframe"))
{
    if (qobject_cast<ArduCopterFirmwarePlugin*>(_vehicle->firmwarePlugin()) != NULL) {
        ParameterManager* paramMgr = _vehicle->parameterManager();
        _requiresFrameSetup = true;
        if (paramMgr->parameterExists(FactSystem::defaultComponentId, _oldFrameParam)) {
            _useNewFrameParam = false;
            _frameParamFact = paramMgr->getParameter(FactSystem::defaultComponentId, _oldFrameParam);
            MAV_TYPE vehicleType = vehicle->vehicleType();
            if (vehicleType == MAV_TYPE_TRICOPTER || vehicleType == MAV_TYPE_HELICOPTER) {
                _requiresFrameSetup = false;
            }
        } else {
            _useNewFrameParam = true;
            _frameParamFact = paramMgr->getParameter(FactSystem::defaultComponentId, _newFrameParam);
        }
    }
}

QString APMAirframeComponent::name(void) const
{
    return _name;
}

QString APMAirframeComponent::description(void) const
{
    return tr("Airframe Setup is used to select the airframe which matches your vehicle. "
              "You can also the load default parameter values associated with known vehicle types.");
}

QString APMAirframeComponent::iconResource(void) const
{
    return QStringLiteral("/qmlimages/AirframeComponentIcon.png");
}

bool APMAirframeComponent::requiresSetup(void) const
{
    return _requiresFrameSetup;
}

bool APMAirframeComponent::setupComplete(void) const
{
    if (_requiresFrameSetup) {
        if (_useNewFrameParam) {
            return _frameParamFact->rawValue().toInt() > 0;
        } else {
            return _frameParamFact->rawValue().toInt() >= 0;
        }
    } else {
        return true;
    }
}

QStringList APMAirframeComponent::setupCompleteChangedTriggerList(void) const
{
    QStringList list;

    if (_requiresFrameSetup) {
        list << (_useNewFrameParam ? _newFrameParam : _oldFrameParam);
    }

    return list;
}

QUrl APMAirframeComponent::setupSource(void) const
{
    if (_requiresFrameSetup) {
        return QUrl::fromUserInput(QStringLiteral("qrc:/qml/APMAirframeComponent.qml"));
    } else {
        return QUrl();
    }
}

QUrl APMAirframeComponent::summaryQmlSource(void) const
{
    if (_requiresFrameSetup) {
        return QUrl::fromUserInput(QStringLiteral("qrc:/qml/APMAirframeComponentSummary.qml"));
    } else {
        return QUrl();
    }
}
<commit_msg><commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "APMAirframeComponent.h"
#include "ArduCopterFirmwarePlugin.h"
#include "ParameterManager.h"

const char* APMAirframeComponent::_oldFrameParam = "FRAME";
const char* APMAirframeComponent::_newFrameParam = "FRAME_CLASS";

APMAirframeComponent::APMAirframeComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
    : VehicleComponent(vehicle, autopilot, parent)
    , _requiresFrameSetup(false)
    , _name(tr("Airframe"))
{
    if (qobject_cast<ArduCopterFirmwarePlugin*>(_vehicle->firmwarePlugin()) != NULL) {
        ParameterManager* paramMgr = _vehicle->parameterManager();
        _requiresFrameSetup = true;
        if (paramMgr->parameterExists(FactSystem::defaultComponentId, _oldFrameParam)) {
            _useNewFrameParam = false;
            _frameParamFact = paramMgr->getParameter(FactSystem::defaultComponentId, _oldFrameParam);
            MAV_TYPE vehicleType = vehicle->vehicleType();
            if (vehicleType == MAV_TYPE_TRICOPTER || vehicleType == MAV_TYPE_HELICOPTER) {
                _requiresFrameSetup = false;
            }
        } else {
            _useNewFrameParam = true;
            _frameParamFact = paramMgr->getParameter(FactSystem::defaultComponentId, _newFrameParam);
        }
    }
}

QString APMAirframeComponent::name(void) const
{
    return _name;
}

QString APMAirframeComponent::description(void) const
{
    return tr("Airframe Setup is used to select the airframe which matches your vehicle.");
}

QString APMAirframeComponent::iconResource(void) const
{
    return QStringLiteral("/qmlimages/AirframeComponentIcon.png");
}

bool APMAirframeComponent::requiresSetup(void) const
{
    return _requiresFrameSetup;
}

bool APMAirframeComponent::setupComplete(void) const
{
    if (_requiresFrameSetup) {
        if (_useNewFrameParam) {
            return _frameParamFact->rawValue().toInt() > 0;
        } else {
            return _frameParamFact->rawValue().toInt() >= 0;
        }
    } else {
        return true;
    }
}

QStringList APMAirframeComponent::setupCompleteChangedTriggerList(void) const
{
    QStringList list;

    if (_requiresFrameSetup) {
        list << (_useNewFrameParam ? _newFrameParam : _oldFrameParam);
    }

    return list;
}

QUrl APMAirframeComponent::setupSource(void) const
{
    if (_requiresFrameSetup) {
        return QUrl::fromUserInput(QStringLiteral("qrc:/qml/APMAirframeComponent.qml"));
    } else {
        return QUrl();
    }
}

QUrl APMAirframeComponent::summaryQmlSource(void) const
{
    if (_requiresFrameSetup) {
        return QUrl::fromUserInput(QStringLiteral("qrc:/qml/APMAirframeComponentSummary.qml"));
    } else {
        return QUrl();
    }
}
<|endoftext|>