<commit_before>//
// Copyright (c) 2011 Kim Walisch, <kim.walisch@gmail.com>.
// All rights reserved.
//
// This file is part of primesieve.
// Visit: http://primesieve.googlecode.com
//
// 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.

#include "ParallelPrimeSieve.h"
#include "PrimeSieve.h"
#include "PrimeNumberFinder.h"
#include "defs.h"
#include "imath.h"

#if defined(_OPENMP)
  #include <omp.h>
#endif

#include <cstdlib>
#include <stdexcept>
#include <algorithm>

ParallelPrimeSieve::ParallelPrimeSieve() :
  numThreads_(USE_IDEAL_NUM_THREADS), shm_(NULL) {
  this->setMinThreadInterval(defs::MIN_THREAD_INTERVAL);
}

/**
 * Get the maximum number of threads allowed for sieving
 * (omp_get_max_threads(), i.e. the number of logical CPU cores).
 */
int ParallelPrimeSieve::getMaxThreads() {
#if defined(_OPENMP)
  return omp_get_max_threads();
#else
  return 1;
#endif
}

/**
 * Get the current set number of threads for sieving.
 */
int ParallelPrimeSieve::getNumThreads() const {
  return (numThreads_ == USE_IDEAL_NUM_THREADS) ? this->getIdealNumThreads()
      : numThreads_;
}

uint64_t ParallelPrimeSieve::getSieveInterval() const {
  return stopNumber_ - startNumber_;
}

/**
 * Get an ideal number of threads for the current set startNumber_,
 * stopNumber_ and flags_.
 */
int ParallelPrimeSieve::getIdealNumThreads() const {
  // 1 thread to print primes in sequential order
  if (flags_ & PRINT_FLAGS)
    return 1;
  // each thread should at least sieve an interval of n^0.5/6 and not
  // smaller than minThreadInterval_ for a performance benefit
  uint64_t threadThreshold = std::max<uint64_t>(
      minThreadInterval_, isqrt(stopNumber_) / 6);

  int idealNumThreads = static_cast<int> (
      std::min<uint64_t>(
          this->getSieveInterval() / threadThreshold,
          this->getMaxThreads()));
  // 1 <= idealNumThreads <= getMaxThreads()
  return std::max<int>(1, idealNumThreads);
}

/**
 * Get a sieve interval that ensures a good load balance among
 * threads.
 */
uint64_t ParallelPrimeSieve::getIdealInterval() const {
  int numThreads = this->getNumThreads();
  if (numThreads == 1)
    return this->getSieveInterval();

  // idealInterval = n^0.5*2000 (0.1 percent initialization overhead)
  uint64_t idealInterval = std::max<uint64_t>(
      minThreadInterval_, isqrt(stopNumber_) * UINT64_C(2000));

  uint64_t maxThreadInterval = this->getSieveInterval() / numThreads;
  // correct the user's thread settings
  if (maxThreadInterval < this->getSieveInterval() &&
      maxThreadInterval < minThreadInterval_)
    maxThreadInterval = this->getSieveInterval() / this->getIdealNumThreads();

  assert(maxThreadInterval == this->getSieveInterval() ||
         maxThreadInterval >= minThreadInterval_);
  return std::min<uint64_t>(idealInterval, maxThreadInterval);
}

/**
 * Set the number of threads for sieving.
 * If numThreads is invalid (numThreads < 1 or > getMaxThreads()) it
 * is set to numThreads = USE_IDEAL_NUM_THREADS.
 */
void ParallelPrimeSieve::setNumThreads(int numThreads) {
  numThreads_ = (numThreads >= 1 && numThreads <= this->getMaxThreads())
      ? numThreads : USE_IDEAL_NUM_THREADS;
}

void ParallelPrimeSieve::setMinThreadInterval(uint64_t minThreadInterval) {
  // prevents gaps when sieving prime k-tuplets in parallel
  if (minThreadInterval < 100)
    throw std::underflow_error(
        "ParallelPrimeSieve: minThreadInterval must be >= 100");
  minThreadInterval_ = minThreadInterval;
}

/**
 * For use with the Qt primesieve application in ../qt-gui.
 * Initializes this ParallelPrimeSieve object with values from a
 * shared memory segment.
 */
void ParallelPrimeSieve::init(SharedMemory* shm) {
  if (shm == NULL)
    throw std::invalid_argument(
        "ParallelPrimeSieve: shared memory segment must not be NULL");
  shm_ = shm;
  this->setStartNumber(shm_->startNumber);
  this->setStopNumber(shm_->stopNumber);
  this->setSieveSize(shm_->sieveSize);
  this->setFlags(shm_->flags);
  this->setNumThreads(shm_->threads);
}

/**
 * Calculate the current status in percent of sieve().
 * @param processed A sieved interval (segment)
 */
void ParallelPrimeSieve::doStatus(uint32_t processed) {
#if defined(_OPENMP)
  #pragma omp critical (doStatus)
#endif
  {
    PrimeSieve::doStatus(processed);
    // communicate the current status via shared memory
    // to the Qt GUI process
    if (shm_ != NULL)
      shm_->status = status_;
  }
}

/**
 * Sieve the prime numbers and/or prime k-tuplets within the interval
 * [startNumber_, stopNumber_] in parallel using OpenMP.
 */
void ParallelPrimeSieve::sieve() {
  if (stopNumber_ < startNumber_)
    throw std::invalid_argument("STOP must be >= START");

#if defined(_OPENMP)
  double t1 = omp_get_wtime();
  this->reset();
  uint64_t idealInterval = this->getIdealInterval();
  uint64_t chunks = this->getSieveInterval() / idealInterval;
  uint64_t maxOffset = chunks * idealInterval;
  uint64_t maxStop = startNumber_ + maxOffset + 32 - maxOffset % 30;
  if (maxStop < stopNumber_)
    chunks++;
  int numThreads = this->getNumThreads();
  // OpenMP parallel sieving
  #pragma omp parallel for num_threads(numThreads) schedule(dynamic)
  for (int64_t i = 0; i < static_cast<int64_t> (chunks); i++) {
    uint64_t start = startNumber_ + idealInterval * i;
    uint64_t stop = startNumber_ + idealInterval * (i+1);
    // the start/stop numbers for PrimeSieve objects must be chosen
    // carefully in order to avoid gaps when sieving prime k-tuplets
    // in parallel
    if (i > 0)
      start += 32 - start % 30;
    stop += 32 - stop % 30;
    // sieve the interval [start, stop]
    PrimeSieve ps(start, std::min<uint64_t>(stop, stopNumber_), this);
    ps.sieve();
    #pragma omp critical (counts)
    for (int j = 0; j < COUNTS_SIZE; j++)
      counts_[j] += ps.getCounts(j);
  }
  timeElapsed_ = omp_get_wtime() - t1;
#else
  PrimeSieve::sieve();
#endif
  // communicate the sieving results via shared memory
  // segment to the Qt GUI process
  if (shm_ != NULL) {
    for (int i = 0; i < COUNTS_SIZE; i++)
      shm_->counts[i] = counts_[i];
    shm_->timeElapsed = timeElapsed_;
  }
}
<commit_msg>include cassert header<commit_after>//
// Copyright (c) 2011 Kim Walisch, <kim.walisch@gmail.com>.
// All rights reserved.
//
// This file is part of primesieve.
// Visit: http://primesieve.googlecode.com
//
// 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.

#include "ParallelPrimeSieve.h"
#include "PrimeSieve.h"
#include "PrimeNumberFinder.h"
#include "defs.h"
#include "imath.h"

#if defined(_OPENMP)
  #include <omp.h>
#endif

#include <cstdlib>
#include <cassert>
#include <stdexcept>
#include <algorithm>

ParallelPrimeSieve::ParallelPrimeSieve() :
  numThreads_(USE_IDEAL_NUM_THREADS), shm_(NULL) {
  this->setMinThreadInterval(defs::MIN_THREAD_INTERVAL);
}

/**
 * Get the maximum number of threads allowed for sieving
 * (omp_get_max_threads(), i.e. the number of logical CPU cores).
 */
int ParallelPrimeSieve::getMaxThreads() {
#if defined(_OPENMP)
  return omp_get_max_threads();
#else
  return 1;
#endif
}

/**
 * Get the current set number of threads for sieving.
 */
int ParallelPrimeSieve::getNumThreads() const {
  return (numThreads_ == USE_IDEAL_NUM_THREADS) ? this->getIdealNumThreads()
      : numThreads_;
}

uint64_t ParallelPrimeSieve::getSieveInterval() const {
  return stopNumber_ - startNumber_;
}

/**
 * Get an ideal number of threads for the current set startNumber_,
 * stopNumber_ and flags_.
 */
int ParallelPrimeSieve::getIdealNumThreads() const {
  // 1 thread to print primes in sequential order
  if (flags_ & PRINT_FLAGS)
    return 1;
  // each thread should at least sieve an interval of n^0.5/6 and not
  // smaller than minThreadInterval_ for a performance benefit
  uint64_t threadThreshold = std::max<uint64_t>(
      minThreadInterval_, isqrt(stopNumber_) / 6);

  int idealNumThreads = static_cast<int> (
      std::min<uint64_t>(
          this->getSieveInterval() / threadThreshold,
          this->getMaxThreads()));
  // 1 <= idealNumThreads <= getMaxThreads()
  return std::max<int>(1, idealNumThreads);
}

/**
 * Get a sieve interval that ensures a good load balance among
 * threads.
 */
uint64_t ParallelPrimeSieve::getIdealInterval() const {
  int numThreads = this->getNumThreads();
  if (numThreads == 1)
    return this->getSieveInterval();

  // idealInterval = n^0.5*2000 (0.1 percent initialization overhead)
  uint64_t idealInterval = std::max<uint64_t>(
      minThreadInterval_, isqrt(stopNumber_) * UINT64_C(2000));

  uint64_t maxThreadInterval = this->getSieveInterval() / numThreads;
  // correct the user's thread settings
  if (maxThreadInterval < this->getSieveInterval() &&
      maxThreadInterval < minThreadInterval_)
    maxThreadInterval = this->getSieveInterval() / this->getIdealNumThreads();

  assert(maxThreadInterval == this->getSieveInterval() ||
         maxThreadInterval >= minThreadInterval_);
  return std::min<uint64_t>(idealInterval, maxThreadInterval);
}

/**
 * Set the number of threads for sieving.
 * If numThreads is invalid (numThreads < 1 or > getMaxThreads()) it
 * is set to numThreads = USE_IDEAL_NUM_THREADS.
 */
void ParallelPrimeSieve::setNumThreads(int numThreads) {
  numThreads_ = (numThreads >= 1 && numThreads <= this->getMaxThreads())
      ? numThreads : USE_IDEAL_NUM_THREADS;
}

void ParallelPrimeSieve::setMinThreadInterval(uint64_t minThreadInterval) {
  // prevents gaps when sieving prime k-tuplets in parallel
  if (minThreadInterval < 100)
    throw std::underflow_error(
        "ParallelPrimeSieve: minThreadInterval must be >= 100");
  minThreadInterval_ = minThreadInterval;
}

/**
 * For use with the Qt primesieve application in ../qt-gui.
 * Initializes this ParallelPrimeSieve object with values from a
 * shared memory segment.
 */
void ParallelPrimeSieve::init(SharedMemory* shm) {
  if (shm == NULL)
    throw std::invalid_argument(
        "ParallelPrimeSieve: shared memory segment must not be NULL");
  shm_ = shm;
  this->setStartNumber(shm_->startNumber);
  this->setStopNumber(shm_->stopNumber);
  this->setSieveSize(shm_->sieveSize);
  this->setFlags(shm_->flags);
  this->setNumThreads(shm_->threads);
}

/**
 * Calculate the current status in percent of sieve().
 * @param processed A sieved interval (segment)
 */
void ParallelPrimeSieve::doStatus(uint32_t processed) {
#if defined(_OPENMP)
  #pragma omp critical (doStatus)
#endif
  {
    PrimeSieve::doStatus(processed);
    // communicate the current status via shared memory
    // to the Qt GUI process
    if (shm_ != NULL)
      shm_->status = status_;
  }
}

/**
 * Sieve the prime numbers and/or prime k-tuplets within the interval
 * [startNumber_, stopNumber_] in parallel using OpenMP.
 */
void ParallelPrimeSieve::sieve() {
  if (stopNumber_ < startNumber_)
    throw std::invalid_argument("STOP must be >= START");

#if defined(_OPENMP)
  double t1 = omp_get_wtime();
  this->reset();
  uint64_t idealInterval = this->getIdealInterval();
  uint64_t chunks = this->getSieveInterval() / idealInterval;
  uint64_t maxOffset = chunks * idealInterval;
  uint64_t maxStop = startNumber_ + maxOffset + 32 - maxOffset % 30;
  if (maxStop < stopNumber_)
    chunks++;
  int numThreads = this->getNumThreads();
  // OpenMP parallel sieving
  #pragma omp parallel for num_threads(numThreads) schedule(dynamic)
  for (int64_t i = 0; i < static_cast<int64_t> (chunks); i++) {
    uint64_t start = startNumber_ + idealInterval * i;
    uint64_t stop = startNumber_ + idealInterval * (i+1);
    // the start/stop numbers for PrimeSieve objects must be chosen
    // carefully in order to avoid gaps when sieving prime k-tuplets
    // in parallel
    if (i > 0)
      start += 32 - start % 30;
    stop += 32 - stop % 30;
    // sieve the interval [start, stop]
    PrimeSieve ps(start, std::min<uint64_t>(stop, stopNumber_), this);
    ps.sieve();
    #pragma omp critical (counts)
    for (int j = 0; j < COUNTS_SIZE; j++)
      counts_[j] += ps.getCounts(j);
  }
  timeElapsed_ = omp_get_wtime() - t1;
#else
  PrimeSieve::sieve();
#endif
  // communicate the sieving results via shared memory
  // segment to the Qt GUI process
  if (shm_ != NULL) {
    for (int i = 0; i < COUNTS_SIZE; i++)
      shm_->counts[i] = counts_[i];
    shm_->timeElapsed = timeElapsed_;
  }
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** 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 Nokia Corporation and its Subsidiary(-ies) 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.
**
****************************************************************************/

#include "waylandsurfaceitem.h"
#include "waylandsurface.h"

#include <qsgengine.h>
#include <private/qsgitem_p.h>

#include <QKeyEvent>

#include <qsgsimpletexturenode.h>
#include <qsgsimplerectnode.h>

void WaylandSurfaceItem::surfaceDamaged(const QRect &)
{
    if (m_texture)
        delete m_texture;

    if (m_surface->type() == WaylandSurface::Texture) {
        m_texture = canvas()->sceneGraphEngine()->createTextureFromId(m_surface->texture(),
                                                                      m_surface->geometry().size());
    } else {
        m_texture = canvas()->sceneGraphEngine()->createTextureFromImage(m_surface->image());
    }

    emit textureChanged();
}

WaylandSurfaceItem::WaylandSurfaceItem(QSGItem *parent)
    : QSGItem(parent)
    , m_surface(0)
    , m_texture(0)
    , m_paintEnabled(true)
{
}

WaylandSurfaceItem::WaylandSurfaceItem(WaylandSurface *surface, QSGItem *parent)
    : QSGItem(parent)
    , m_surface(0)
    , m_texture(0)
    , m_paintEnabled(true)
{
    init(surface);
}

void WaylandSurfaceItem::init(WaylandSurface *surface)
{
    if (!surface)
        return;

    m_surface = surface;

    setWidth(surface->geometry().width());
    setHeight(surface->geometry().height());

    setSmooth(true);
    setFlag(ItemHasContents);
    setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
    connect(surface, SIGNAL(mapped(const QRect &)), this, SLOT(surfaceMapped(const QRect &)));
    connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
    connect(this, SIGNAL(textureChanged()), this, SLOT(update()));
    connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
}

WaylandSurfaceItem::~WaylandSurfaceItem()
{
    delete m_texture;
}

void WaylandSurfaceItem::setSurface(WaylandSurface *surface)
{
    init(surface);
}

bool WaylandSurfaceItem::isYInverted() const
{
    return m_surface->isYInverted();
}

QSGTexture *WaylandSurfaceItem::texture() const
{
    if (m_texture)
        m_texture->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
    return m_texture;
}

void WaylandSurfaceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMousePressEvent(toSurface(event->pos()), event->button());
}

void WaylandSurfaceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMouseMoveEvent(toSurface(event->pos()));
}

void WaylandSurfaceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMouseReleaseEvent(toSurface(event->pos()), event->button());
}

void WaylandSurfaceItem::keyPressEvent(QKeyEvent *event)
{
    if (m_surface && hasFocus())
        m_surface->sendKeyPressEvent(event->nativeScanCode());
}

void WaylandSurfaceItem::keyReleaseEvent(QKeyEvent *event)
{
    if (m_surface && hasFocus())
        m_surface->sendKeyReleaseEvent(event->nativeScanCode());
}

void WaylandSurfaceItem::takeFocus()
{
    setFocus(true);

    if (m_surface)
        m_surface->setInputFocus();
}

QPoint WaylandSurfaceItem::toSurface(const QPointF &pos) const
{
    return pos.toPoint();
}

void WaylandSurfaceItem::surfaceMapped(const QRect &rect)
{
    setWidth(rect.width());
    setHeight(rect.height());
}

void WaylandSurfaceItem::surfaceDestroyed(QObject *)
{
    m_surface = 0;
}

bool WaylandSurfaceItem::paintEnabled() const
{
    return m_paintEnabled;
}

void WaylandSurfaceItem::setPaintEnabled(bool enabled)
{
    m_paintEnabled = enabled;
    update();
}

QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);

    if (!m_texture || !m_paintEnabled) {
        delete oldNode;
        return 0;
    }

    if (!node) {
        node = new QSGSimpleTextureNode();
    }

    if (surface()->isYInverted()) {
        node->setRect(0, height(), width(), -height());
    } else {
        node->setRect(0, 0, width(), height());
    }

    node->setTexture(m_texture);

    node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);

    return node;
}
<commit_msg>Fixed missing texture updates.<commit_after>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** 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 Nokia Corporation and its Subsidiary(-ies) 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.
**
****************************************************************************/

#include "waylandsurfaceitem.h"
#include "waylandsurface.h"

#include <qsgengine.h>
#include <private/qsgitem_p.h>

#include <QKeyEvent>

#include <qsgsimpletexturenode.h>
#include <qsgsimplerectnode.h>

void WaylandSurfaceItem::surfaceDamaged(const QRect &)
{
    QSGTexture *oldTexture = m_texture;

    if (m_surface->type() == WaylandSurface::Texture) {
        m_texture = canvas()->sceneGraphEngine()->createTextureFromId(m_surface->texture(),
                                                                      m_surface->geometry().size());
    } else {
        m_texture = canvas()->sceneGraphEngine()->createTextureFromImage(m_surface->image());
    }

    delete oldTexture;

    emit textureChanged();
}

WaylandSurfaceItem::WaylandSurfaceItem(QSGItem *parent)
    : QSGItem(parent)
    , m_surface(0)
    , m_texture(0)
    , m_paintEnabled(true)
{
}

WaylandSurfaceItem::WaylandSurfaceItem(WaylandSurface *surface, QSGItem *parent)
    : QSGItem(parent)
    , m_surface(0)
    , m_texture(0)
    , m_paintEnabled(true)
{
    init(surface);
}

void WaylandSurfaceItem::init(WaylandSurface *surface)
{
    if (!surface)
        return;

    m_surface = surface;

    setWidth(surface->geometry().width());
    setHeight(surface->geometry().height());

    setSmooth(true);
    setFlag(ItemHasContents);
    setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
    connect(surface, SIGNAL(mapped(const QRect &)), this, SLOT(surfaceMapped(const QRect &)));
    connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
    connect(this, SIGNAL(textureChanged()), this, SLOT(update()));
    connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
}

WaylandSurfaceItem::~WaylandSurfaceItem()
{
    delete m_texture;
}

void WaylandSurfaceItem::setSurface(WaylandSurface *surface)
{
    init(surface);
}

bool WaylandSurfaceItem::isYInverted() const
{
    return m_surface->isYInverted();
}

QSGTexture *WaylandSurfaceItem::texture() const
{
    if (m_texture)
        m_texture->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
    return m_texture;
}

void WaylandSurfaceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMousePressEvent(toSurface(event->pos()), event->button());
}

void WaylandSurfaceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMouseMoveEvent(toSurface(event->pos()));
}

void WaylandSurfaceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_surface)
        m_surface->sendMouseReleaseEvent(toSurface(event->pos()), event->button());
}

void WaylandSurfaceItem::keyPressEvent(QKeyEvent *event)
{
    if (m_surface && hasFocus())
        m_surface->sendKeyPressEvent(event->nativeScanCode());
}

void WaylandSurfaceItem::keyReleaseEvent(QKeyEvent *event)
{
    if (m_surface && hasFocus())
        m_surface->sendKeyReleaseEvent(event->nativeScanCode());
}

void WaylandSurfaceItem::takeFocus()
{
    setFocus(true);

    if (m_surface)
        m_surface->setInputFocus();
}

QPoint WaylandSurfaceItem::toSurface(const QPointF &pos) const
{
    return pos.toPoint();
}

void WaylandSurfaceItem::surfaceMapped(const QRect &rect)
{
    setWidth(rect.width());
    setHeight(rect.height());
}

void WaylandSurfaceItem::surfaceDestroyed(QObject *)
{
    m_surface = 0;
}

bool WaylandSurfaceItem::paintEnabled() const
{
    return m_paintEnabled;
}

void WaylandSurfaceItem::setPaintEnabled(bool enabled)
{
    m_paintEnabled = enabled;
    update();
}

QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);

    if (!m_texture || !m_paintEnabled) {
        delete oldNode;
        return 0;
    }

    if (!node) {
        node = new QSGSimpleTextureNode();
    }

    if (surface()->isYInverted()) {
        node->setRect(0, height(), width(), -height());
    } else {
        node->setRect(0, 0, width(), height());
    }

    node->setTexture(m_texture);

    node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);

    return node;
}
<|endoftext|>


<commit_before>//
//  Entity.hpp
//  1v1_neckbeard_server
//
//  Created by Filip Peterek on 01/01/2017.
//  Copyright © 2017 Filip Peterek. All rights reserved.
//

#ifndef Entity_hpp
#define Entity_hpp

#include <stdio.h>
#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

#include "macros.hpp"

enum class direction {

    left = LEFT,
    right = RIGHT

};

class entity {

protected:
    direction _dir;
    char _hp;
    unsigned char _sprite;
    sf::Vector2f _pos;

public:

    /* These all just return a reference since they are freely modifiable anyway and getters make no sense */
    direction & direction();
    char & hp();
    sf::Vector2f & position();

    /* Just for polymorphism */
    virtual unsigned char & sprite();
    virtual unsigned short victoryCounter() = 0;

};

#endif /* Entity_hpp */
<commit_msg>Update Entity.hpp<commit_after>//
//  Entity.hpp
//  1v1_neckbeard_server
//
//  Created by Filip Peterek on 01/01/2017.
//  Copyright © 2017 Filip Peterek. All rights reserved.
//

#ifndef Entity_hpp
#define Entity_hpp

#include <stdio.h>
#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

#include "macros.hpp"

enum class direction {

    left = LEFT,
    right = RIGHT

};

class entity {

protected:
    direction _dir;
    char _hp;
    unsigned char _sprite;
    sf::Vector2f _pos;

public:

    /* These all just return a reference since they are freely modifiable anyway and getters make no sense */
    direction & getDirection();
    char & hp();
    sf::Vector2f & position();

    /* Just for polymorphism */
    virtual unsigned char & sprite();
    virtual unsigned short victoryCounter() = 0;

};

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


<commit_before>//
// Created by Sam on 9/25/2017.
//

#include "../include/Game/Core/Card.h"
#include "../include/Game/Core/Game.h"
#include "../include/Game/Core/Player.h"
#include "../include/Game/Python/Factory.h"
#include "../include/Game/Derived/Card/Creature.h"
#include "../include/Network/Server.h"

#include <pybind11/embed.h>

namespace py = pybind11;

void commandListen(std::shared_ptr<Server> server)
{
    std::__cxx11::string line;
    while (getline(std::cin, line) && line != "quit")
    {
        if (line == "memes")
        {
            auto card = server->factory.createCard("Azar");
            auto creature = std::dynamic_pointer_cast<Creature>(card);

            std::cout << creature->getJSON().dump(4) << std::endl;
        }
        else if (line == "list")
        {
            for (const auto &client : server->clients)
            {
                if (!client->name.empty())
                {
                    std::cout << client->name << std::endl;
                }
            }
            std::cout << server->clients.size() << " client(s) connected" << std::endl;
        }
        else
        {
            std::cout << "Unknown command: '" << line << "'" << std::endl;
        }
    }

    std::cout << "Shutting down..." << std::endl;
    server->Stop();
    std::cout << "Bye!" << std::endl;
}

int main(int argc, const char* argv[])
{
    bool process = false;

    for(int i = 0; i < argc; ++i)
    {
        if(std::string(argv[i]) == "-process")
        {
            process = true;
        }
    }

    auto server = std::make_shared<Server>(8888);
    server->Start();

    if (process)
    {
        while(true){}
    }
    else
    {
        commandListen(server);
    }
}
<commit_msg>Call the new camelCase functions for the server<commit_after>//
// Created by Sam on 9/25/2017.
//

#include "../include/Game/Core/Card.h"
#include "../include/Game/Core/Game.h"
#include "../include/Game/Core/Player.h"
#include "../include/Game/Python/Factory.h"
#include "../include/Game/Derived/Card/Creature.h"
#include "../include/Network/Server.h"

#include <pybind11/embed.h>

namespace py = pybind11;

void commandListen(std::shared_ptr<Server> server)
{
    std::__cxx11::string line;
    while (getline(std::cin, line) && line != "quit")
    {
        if (line == "memes")
        {
            auto card = server->factory.createCard("Azar");
            auto creature = std::dynamic_pointer_cast<Creature>(card);

            std::cout << creature->getJSON().dump(4) << std::endl;
        }
        else if (line == "list")
        {
            for (const auto &client : server->clients)
            {
                if (!client->name.empty())
                {
                    std::cout << client->name << std::endl;
                }
            }
            std::cout << server->clients.size() << " client(s) connected" << std::endl;
        }
        else
        {
            std::cout << "Unknown command: '" << line << "'" << std::endl;
        }
    }

    std::cout << "Shutting down..." << std::endl;
    server->stop();
    std::cout << "Bye!" << std::endl;
}

int main(int argc, const char* argv[])
{
    bool process = false;

    for(int i = 0; i < argc; ++i)
    {
        if(std::string(argv[i]) == "-process")
        {
            process = true;
        }
    }

    auto server = std::make_shared<Server>(8888);
    server->start();

    if (process)
    {
        while(true){}
    }
    else
    {
        commandListen(server);
    }
}
<|endoftext|>


<commit_before>/*
  FileSystem.cpp - SPIFS implementation for esp8266

  Copyright (c) 2015 Hristo Gochkov. All rights reserved.
  This file is part of the esp8266 core for Arduino environment.

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

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

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include "FileSystem.h"
#include "Arduino.h"

bool FSClass::mount() {
  if (_mounted)
    return true;

  _mounted = spiffs_mount();
  return _mounted;
}

void FSClass::unmount() {
  if (!_mounted)
    return;

  spiffs_unmount();
  _mounted = false;
}

bool FSClass::format() {
  return spiffs_format();
}

bool FSClass::exists(const char *filename) {
  spiffs_stat stat = {0};
  if (SPIFFS_stat(&_filesystemStorageHandle, filename, &stat) < 0)
    return false;
  return stat.name[0] != '\0';
}

bool FSClass::create(const char *filepath){
  return SPIFFS_creat(&_filesystemStorageHandle, filepath, 0) == 0;
}

bool FSClass::remove(const char *filepath){
  return SPIFFS_remove(&_filesystemStorageHandle, filepath) == 0;
}

bool FSClass::rename(const char *filename, const char *newname) {
  return SPIFFS_rename(&_filesystemStorageHandle, filename, newname) == 0;
}

FSFile FSClass::open(const char *filename, uint8_t mode) {
  int repeats = 0;
  bool notExist;
  bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
  int res;

  do{
    notExist = false;
    res = SPIFFS_open(&_filesystemStorageHandle, filename, (spiffs_flags)mode, 0);
    int code = SPIFFS_errno(&_filesystemStorageHandle);
    if (res < 0){
      debugf("open errno %d\n", code);
      notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
      if (notExist && canRecreate)
        remove(filename); // fix for deleted files
    }
  } while (notExist && canRecreate && repeats++ < 3);

  if(res){
    return FSFile(res);
  }
  return FSFile();
}

FSClass FS;

FSFile::FSFile() {
  _file = 0;
  _stats = {0};
}

FSFile::FSFile(file_t f) {
  _file = f;
  if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
    debugf("mount errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
  }
}

void FSFile::close() {
  if (! _file) return;
  SPIFFS_close(&_filesystemStorageHandle, _file);
  _file = 0;
}

uint32_t FSFile::size() {
  if(! _file) return 0;
  uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
  uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
  return size;
}

uint32_t FSFile::seek(uint32_t pos) {
  if (! _file) return 0;
  return SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
}

uint32_t FSFile::position() {
  if (! _file) return 0;
  return SPIFFS_tell(&_filesystemStorageHandle, _file);
}

bool FSFile::eof() {
  if (! _file) return 0;
  return SPIFFS_eof(&_filesystemStorageHandle, _file);
}

bool FSFile::isDirectory(void) {
  return false;
}

int FSFile::read(void *buf, uint16_t nbyte) {
  if (! _file) return -1;
  return SPIFFS_read(&_filesystemStorageHandle, _file, buf, nbyte);
}

int FSFile::read() {
  if (! _file) return -1;
  int val;
  if(SPIFFS_read(&_filesystemStorageHandle, _file, &val, 1) != 1) return -1;
  return val;
}

int FSFile::peek() {
  if (! _file) return 0;
  int c = read();
  SPIFFS_lseek(&_filesystemStorageHandle, _file, -1, SPIFFS_SEEK_CUR);
  return c;
}

int FSFile::available() {
  if (! _file) return 0;
  uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
  uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
  return size - pos;
}

size_t FSFile::write(const uint8_t *buf, size_t size){
  if (! _file) return 0;
  return SPIFFS_write(&_filesystemStorageHandle, _file, (uint8_t *)buf, size);
}

size_t FSFile::write(uint8_t val) {
  if (! _file) return 0;
  return write(&val, 1);
}

void FSFile::flush(){
  if (! _file) return;
  SPIFFS_fflush(&_filesystemStorageHandle, _file);
}

uint32_t FSFile::remove(){
  if (! _file) return 0;
	return SPIFFS_fremove(&_filesystemStorageHandle, _file);
  _file = 0;
}

int FSFile::lastError(){
  return SPIFFS_errno(&_filesystemStorageHandle);
}

void FSFile::clearError(){
  _filesystemStorageHandle.errno = SPIFFS_OK;
}

char * FSFile::name(){
  return 0;
}

/*
spiffs_DIR *dirOpen(spiffs_DIR *d){
  return SPIFFS_opendir(&_filesystemStorageHandle, 0, d);
}

int dirClose(spiffs_DIR *d){
  return SPIFFS_closedir(d);
}

file_t dirOpenFile(spiffs_dirent* entry, uint8_t flags){
  return SPIFFS_open_by_dirent(&_filesystemStorageHandle, entry, (spiffs_flags)flags, 0);
}
*/
<commit_msg>make sure write return a positive or zero value<commit_after>/*
  FileSystem.cpp - SPIFS implementation for esp8266

  Copyright (c) 2015 Hristo Gochkov. All rights reserved.
  This file is part of the esp8266 core for Arduino environment.

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

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

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include "FileSystem.h"
#include "Arduino.h"

bool FSClass::mount() {
  if (_mounted)
    return true;

  _mounted = spiffs_mount();
  return _mounted;
}

void FSClass::unmount() {
  if (!_mounted)
    return;

  spiffs_unmount();
  _mounted = false;
}

bool FSClass::format() {
  return spiffs_format();
}

bool FSClass::exists(const char *filename) {
  spiffs_stat stat = {0};
  if (SPIFFS_stat(&_filesystemStorageHandle, filename, &stat) < 0)
    return false;
  return stat.name[0] != '\0';
}

bool FSClass::create(const char *filepath){
  return SPIFFS_creat(&_filesystemStorageHandle, filepath, 0) == 0;
}

bool FSClass::remove(const char *filepath){
  return SPIFFS_remove(&_filesystemStorageHandle, filepath) == 0;
}

bool FSClass::rename(const char *filename, const char *newname) {
  return SPIFFS_rename(&_filesystemStorageHandle, filename, newname) == 0;
}

FSFile FSClass::open(const char *filename, uint8_t mode) {
  int repeats = 0;
  bool notExist;
  bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
  int res;

  do{
    notExist = false;
    res = SPIFFS_open(&_filesystemStorageHandle, filename, (spiffs_flags)mode, 0);
    int code = SPIFFS_errno(&_filesystemStorageHandle);
    if (res < 0){
      debugf("open errno %d\n", code);
      notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
      if (notExist && canRecreate)
        remove(filename); // fix for deleted files
    }
  } while (notExist && canRecreate && repeats++ < 3);

  if(res){
    return FSFile(res);
  }
  return FSFile();
}

FSClass FS;

FSFile::FSFile() {
  _file = 0;
  _stats = {0};
}

FSFile::FSFile(file_t f) {
  _file = f;
  if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
    debugf("mount errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
  }
}

void FSFile::close() {
  if (! _file) return;
  SPIFFS_close(&_filesystemStorageHandle, _file);
  _file = 0;
}

uint32_t FSFile::size() {
  if(! _file) return 0;
  uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
  uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
  return size;
}

uint32_t FSFile::seek(uint32_t pos) {
  if (! _file) return 0;
  return SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
}

uint32_t FSFile::position() {
  if (! _file) return 0;
  return SPIFFS_tell(&_filesystemStorageHandle, _file);
}

bool FSFile::eof() {
  if (! _file) return 0;
  return SPIFFS_eof(&_filesystemStorageHandle, _file);
}

bool FSFile::isDirectory(void) {
  return false;
}

int FSFile::read(void *buf, uint16_t nbyte) {
  if (! _file) return -1;
  return SPIFFS_read(&_filesystemStorageHandle, _file, buf, nbyte);
}

int FSFile::read() {
  if (! _file) return -1;
  int val;
  if(SPIFFS_read(&_filesystemStorageHandle, _file, &val, 1) != 1) return -1;
  return val;
}

int FSFile::peek() {
  if (! _file) return 0;
  int c = read();
  SPIFFS_lseek(&_filesystemStorageHandle, _file, -1, SPIFFS_SEEK_CUR);
  return c;
}

int FSFile::available() {
  if (! _file) return 0;
  uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
  uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
  SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
  return size - pos;
}

size_t FSFile::write(const uint8_t *buf, size_t size){
  if (! _file) return 0;
  int res = SPIFFS_write(&_filesystemStorageHandle, _file, (uint8_t *)buf, size);
  return (res > 0)?res:0;
}

size_t FSFile::write(uint8_t val) {
  if (! _file) return 0;
  return write(&val, 1);
}

void FSFile::flush(){
  if (! _file) return;
  SPIFFS_fflush(&_filesystemStorageHandle, _file);
}

uint32_t FSFile::remove(){
  if (! _file) return 0;
	return SPIFFS_fremove(&_filesystemStorageHandle, _file);
  _file = 0;
}

int FSFile::lastError(){
  return SPIFFS_errno(&_filesystemStorageHandle);
}

void FSFile::clearError(){
  _filesystemStorageHandle.errno = SPIFFS_OK;
}

char * FSFile::name(){
  return 0;
}

/*
spiffs_DIR *dirOpen(spiffs_DIR *d){
  return SPIFFS_opendir(&_filesystemStorageHandle, 0, d);
}

int dirClose(spiffs_DIR *d){
  return SPIFFS_closedir(d);
}

file_t dirOpenFile(spiffs_dirent* entry, uint8_t flags){
  return SPIFFS_open_by_dirent(&_filesystemStorageHandle, entry, (spiffs_flags)flags, 0);
}
*/
<|endoftext|>


<commit_before>// Copyright 2014 eric schkufza, stefan heule
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <string>
#include <utility>

#include "src/ext/cpputil/include/serialize/text_reader.h"
#include "src/ext/cpputil/include/serialize/text_writer.h"

#include "src/ext/x64asm/src/opcode.h"

#include "tools/io/opc_set.h"
#include "tools/io/generic.h"

using namespace cpputil;
using namespace std;
using namespace x64asm;

namespace {

array<const char*, 3801> att_ {{
    // Internal mnemonics
    "<label definition>"
    // Auto-generated mnemonics
#include "src/ext/x64asm/src/opcode.att"
  }};

array<const char*, 59> types_ {{
    "hint",
    "imm8",
    "imm16",
    "imm32",
    "imm64",
    "zero",
    "one",
    "three",
    "label",
    "m8",
    "m16",
    "m32",
    "m64",
    "m128",
    "m256",
    "m16int",
    "m32int",
    "m64int",
    "m32fp",
    "m64fp",
    "m80fp",
    "m80bcd",
    "m2byte",
    "m28byte",
    "m108byte",
    "m512byte",
    "farptr1616",
    "farptr1632",
    "farptr1664",
    "mm",
    "pref66",
    "prefrexw",
    "far",
    "moffs8",
    "moffs16",
    "moffs32",
    "moffs64",
    "rl",
    "rh",
    "rb",
    "al",
    "cl",
    "r16",
    "ax",
    "dx",
    "r32",
    "eax",
    "r64",
    "rax",
    "rel8",
    "rel32",
    "sreg",
    "fs",
    "gs",
    "st",
    "st0",
    "xmm",
    "xmm0",
    "ymm"
  }};

}

namespace stoke {

void OpcSetReader::operator()(istream& is, set<Opcode>& os) {
  vector<string> args;
  TextReader<vector<string>>()(is, args);

  for (const auto& a : args) {
    bool found = false;
    int i = 0;
    for (int i = ADC_AL_IMM8; i <= XTEST; i++) {
      Opcode opcode = static_cast<Opcode>(i);
      string str = opcode_to_string(opcode);
      if (str.find(a) == 0) {
        found = true;
        os.insert(opcode);
      }
    }
    if (!found) {
      is.setstate(ios::failbit);
      return;
    }
  }
}

void OpcSetWriter::operator()(ostream& os, const set<Opcode>& ocs) {
  os << "{";
  set<const char*> result;
  for (auto opc : ocs) {
    os << " ";
    os << opcode_to_string(opc);
  }
  os << " }";
}

string opcode_to_string(Opcode op) {
  Instruction instr(op);
  string result(att_[op]);
  for (size_t i = 0; i < instr.arity(); i++) {
    result += "_";
    result += types_[(int)instr.type(i)];
  }
  return result;
}

} // namespace stoke

<commit_msg>Fix 198.<commit_after>// Copyright 2014 eric schkufza, stefan heule
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <string>
#include <utility>

#include "src/ext/cpputil/include/serialize/text_reader.h"
#include "src/ext/cpputil/include/serialize/text_writer.h"

#include "src/ext/x64asm/src/opcode.h"

#include "tools/io/opc_set.h"
#include "tools/io/generic.h"

using namespace cpputil;
using namespace std;
using namespace x64asm;

namespace {

array<const char*, 3801> att_ {{
    // Internal mnemonics
    "<label definition>"
    // Auto-generated mnemonics
#include "src/ext/x64asm/src/opcode.att"
  }};

array<const char*, 59> types_ {{
    "hint",
    "imm8",
    "imm16",
    "imm32",
    "imm64",
    "zero",
    "one",
    "three",
    "label",
    "m8",
    "m16",
    "m32",
    "m64",
    "m128",
    "m256",
    "m16int",
    "m32int",
    "m64int",
    "m32fp",
    "m64fp",
    "m80fp",
    "m80bcd",
    "m2byte",
    "m28byte",
    "m108byte",
    "m512byte",
    "farptr1616",
    "farptr1632",
    "farptr1664",
    "mm",
    "pref66",
    "prefrexw",
    "far",
    "moffs8",
    "moffs16",
    "moffs32",
    "moffs64",
    "rl",
    "rh",
    "rb",
    "al",
    "cl",
    "r16",
    "ax",
    "dx",
    "r32",
    "eax",
    "r64",
    "rax",
    "rel8",
    "rel32",
    "sreg",
    "fs",
    "gs",
    "st",
    "st0",
    "xmm",
    "xmm0",
    "ymm"
  }};

}

namespace stoke {

void OpcSetReader::operator()(istream& is, set<Opcode>& os) {
  vector<string> args;
  TextReader<vector<string>>()(is, args);

  for (const auto& a : args) {
    bool found = false;
    int i = 0;
    for (int i = ADC_AL_IMM8; i <= XTEST; i++) {
      Opcode opcode = static_cast<Opcode>(i);
      string str = opcode_to_string(opcode);
      if (str.find(a) == 0) {
        found = true;
        os.insert(opcode);
      }
    }
    if (!found) {
      is.setstate(ios::failbit);
      return;
    }
  }
}

void OpcSetWriter::operator()(ostream& os, const set<Opcode>& ocs) {
  os << "{";
  set<const char*> result;
  for (auto opc : ocs) {
    os << " ";
    os << opcode_to_string(opc);
  }
  os << " }";
}

string opcode_to_string(Opcode op) {
  Instruction instr(op);
  string result(att_[op]);
  for (size_t i = 0; i < instr.arity(); i++) {
    result += "_";
    result += types_[(int)instr.type(i)-1];
  }
  return result;
}

} // namespace stoke

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: hashtbl.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-14 11:36:19 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "hashtbl.hxx"
#include <string.h>

// -------------------------------------------------------------
// class HashItem
//
class HashItem
{
    enum ETag { TAG_EMPTY, TAG_USED, TAG_DELETED };

    void*   m_pObject;
    ETag    m_Tag;
    char*   m_Key;

public:
    HashItem() { m_Tag = TAG_EMPTY; m_Key = NULL; m_pObject = NULL; }
    ~HashItem() { delete [] m_Key; }

    bool IsDeleted() const
    {   return m_Tag == TAG_DELETED; }

    bool IsEmpty() const
    {   return m_Tag == TAG_DELETED || m_Tag == TAG_EMPTY; }

    bool IsFree() const
    {   return m_Tag == TAG_EMPTY; }

    bool IsUsed() const
    {   return m_Tag == TAG_USED; }

    void Delete()
    { m_Tag = TAG_DELETED; delete [] m_Key; m_Key = new char[ 1 ]; m_Key[ 0 ] = 0; m_pObject = NULL; }

    const char *GetKey() const
    { return m_Key; }

    void* GetObject() const
    { return m_pObject; }

    void SetObject(const char * Key, void *pObject)
    { m_Tag = TAG_USED; delete [] m_Key; m_Key = new char[ strlen( Key ) + 1 ]; strcpy( m_Key, Key ); m_pObject = pObject; }
};

#define MIN(a,b) (a)<(b)?(a):(b)
#define MAX(a,b) (a)>(b)?(a):(b)

// -------------------------------------------------------------
// class HashTable
//

/*static*/ double HashTable::m_defMaxLoadFactor = 0.5;
/*static*/ double HashTable::m_defDefGrowFactor = 2.0;

HashTable::HashTable(unsigned long lSize, bool bOwner, double dMaxLoadFactor, double dGrowFactor)
{
    m_lSize          = lSize;
    m_bOwner         = bOwner;
    m_lElem          = 0;
    m_dMaxLoadFactor = MAX(0.5,MIN(1.0,dMaxLoadFactor));  // 0.5 ... 1.0
    m_dGrowFactor    = MAX(2.0,MIN(5.0,dGrowFactor));     // 1.3 ... 5.0
    m_pData          = new HashItem [lSize];
}

HashTable::~HashTable()
{
    // Wenn die HashTable der Owner der Objecte ist,
    // mssen die Destruktoren separat gerufen werden.
    // Dies geschieht ber die virtuelle Methode OnDeleteObject()
    //
    // Problem: Virtuelle Funktionen sind im Destructor nicht virtuell!!
    //          Der Code mu deshalb ins Macro

    /*
    if (m_bOwner)
    {
        for (ULONG i=0; i<GetSize(); i++)
        {
            void *pObject = GetObjectAt(i);

            if (pObject != NULL)
                OnDeleteObject(pObject());
        }
    }
    */

    // Speicher fr HashItems freigeben
    delete [] m_pData;
}

void* HashTable::GetObjectAt(unsigned long lPos) const
// Gibt Objekt zurck, wenn es eines gibt, sonst NULL;
{
    HashItem *pItem = &m_pData[lPos];

    return pItem->IsUsed() ? pItem->GetObject() : NULL;
}

void HashTable::OnDeleteObject(void*)
{
}

unsigned long HashTable::Hash(const char *Key) const
{
    // Hashfunktion von P.J. Weinberger
    // aus dem "Drachenbuch" von Aho/Sethi/Ullman
    unsigned long i,n;
    unsigned long h = 0;
    unsigned long g = 0;

    for (i=0,n=strlen( Key ); i<n; i++)
    {
        h = (h<<4) + (unsigned long)(unsigned short)Key[i];
        g = h & 0xf0000000;

        if (g != 0)
        {
            h = h ^ (g >> 24);
            h = h ^ g;
        }
    }

    return h % m_lSize;
}

unsigned long HashTable::DHash(const char* Key, unsigned long lOldHash) const
{
    unsigned long lHash = lOldHash;
    unsigned long i,n;

    for (i=0,n=strlen( Key ); i<n; i++)
    {
        lHash *= 256L;
        lHash += (unsigned long)(unsigned short)Key[i];
        lHash %= m_lSize;
    }
    return lHash;
}

unsigned long HashTable::Probe(unsigned long lPos) const
// gibt den Folgewert von lPos zurck
{
    lPos++; if (lPos==m_lSize) lPos=0;
    return lPos;
}

bool HashTable::IsFull() const
{
    return m_lElem>=m_lSize;
}

bool HashTable::Insert(const char * Key, void* pObject)
// pre:  Key ist nicht im Dictionary enthalten, sonst return FALSE
//       Dictionary ist nicht voll, sonst return FALSE
// post: pObject ist unter Key im Dictionary; m_nElem wurde erhht
{
    SmartGrow();

    if (IsFull())
    {
        return false;
    }

    if (FindPos(Key) != NULL )
        return false;

    unsigned long     lPos  = Hash(Key);
    HashItem *pItem = &m_pData[lPos];

    // first hashing
    //
    if (pItem->IsEmpty())
    {
        pItem->SetObject(Key, pObject);
        m_lElem++;

        return true;
    }

    // double hashing
    //
    lPos  = DHash(Key,lPos);
    pItem = &m_pData[lPos];

    if (pItem->IsEmpty())
    {
        pItem->SetObject(Key, pObject);
        m_lElem++;

        return true;
    }

    // linear probing
    //
    do
    {
        lPos  = Probe(lPos);
        pItem = &m_pData[lPos];
    }
    while(!pItem->IsEmpty());

    pItem->SetObject(Key, pObject);
    m_lElem++;
    return true;
}

HashItem* HashTable::FindPos(const char * Key) const
// sucht den Key; gibt Refrenz auf den Eintrag (gefunden)
// oder NULL (nicht gefunden) zurck
//
// pre:  -
// post: -
{
    // first hashing
    //
    unsigned long     lPos  = Hash(Key);
    HashItem *pItem = &m_pData[lPos];

    if (pItem->IsUsed()
    &&  !(strcmp( pItem->GetKey(), Key )))
    {
        return pItem;
    }

    // double hashing
    //
    if (pItem->IsDeleted() || pItem->IsUsed())
    {
        lPos  = DHash(Key,lPos);
        pItem = &m_pData[lPos];

        if (pItem->IsUsed()
        &&  (!strcmp( pItem->GetKey(), Key)))
        {
            return pItem;
        }

        // linear probing
        //
        if (pItem->IsDeleted() || pItem->IsUsed())
        {
            unsigned long n      = 0;
            bool  bFound = false;
            bool  bEnd   = false;

            do
            {
                n++;
                lPos   = Probe(lPos);
                pItem  = &m_pData[lPos];

                bFound =  pItem->IsUsed()
                       && !( strcmp( pItem->GetKey(), Key ));

                bEnd = !(n<m_lSize || pItem->IsFree());
            }
            while(!bFound && !bEnd);

            return bFound ? pItem : NULL;
        }
    }

    // nicht gefunden
    //
    return NULL;
}

void* HashTable::Find(const char *Key) const
// Gibt Verweis des Objektes zurck, das unter Key abgespeichert ist,
// oder NULL wenn nicht vorhanden.
//
// pre:  -
// post: -
{
    HashItem *pItem = FindPos(Key);

    if (pItem != NULL
    && ( !strcmp( pItem->GetKey(), Key )))
        return pItem->GetObject();
    else
        return NULL;
}

void* HashTable::Delete( const char * Key)
// Lscht Objekt, das unter Key abgespeichert ist und gibt Verweis
// darauf zurck.
// Gibt NULL zurck, wenn Key nicht vorhanden ist.
//
// pre:  -
// post: Objekt ist nicht mehr enthalten; m_lElem dekrementiert
//       Wenn die HashTable der Owner ist, wurde das Object gelscht
{
    HashItem *pItem = FindPos(Key);

    if (pItem != NULL
    &&  ( !strcmp( pItem->GetKey(), Key )))
    {
        void* pObject = pItem->GetObject();

        if (m_bOwner)
            OnDeleteObject(pObject);

        pItem->Delete();
        m_lElem--;
        return pObject;
    }
    else
    {
        return NULL;
    }
}

double HashTable::CalcLoadFactor() const
// prozentuale Belegung der Hashtabelle berechnen
{
    return double(m_lElem) / double(m_lSize);
}

void HashTable::SmartGrow()
// Achtung: da die Objekte umkopiert werden, darf die OnDeleteObject-Methode
//          nicht gerufen werden
{
    double dLoadFactor = CalcLoadFactor();

    if (dLoadFactor <= m_dMaxLoadFactor)
        return; // nothing to grow

    unsigned long     lOldSize = m_lSize;              // alte Daten sichern
    HashItem* pOldData = m_pData;

    m_lSize = unsigned long (m_dGrowFactor * m_lSize); // neue Gre
    m_pData = new HashItem[m_lSize];           // neue Daten holen

    // kein Speicher:
    // Zustand "Tabelle voll" wird in Insert abgefangen
    //
    if (m_pData == NULL)
    {
        m_lSize = lOldSize;
        m_pData = pOldData;
        return;
    }

    m_lElem = 0;                               // noch keine neuen Daten

    // Umkopieren der Daten
    //
    for (unsigned long i=0; i<lOldSize; i++)
    {
        HashItem *pItem = &pOldData[i];

        if (pItem->IsUsed())
            Insert(pItem->GetKey(),pItem->GetObject());
    }

    delete [] pOldData;
}

// Iterator ---------------------------------------------------------
//

HashTableIterator::HashTableIterator(HashTable const& aTable)
: m_aTable(aTable)
{
    m_lAt = 0;
}

void* HashTableIterator::GetFirst()
{
    m_lAt = 0;
    return FindValidObject(true /* forward */);
}

void* HashTableIterator::GetLast()
{
    m_lAt = m_aTable.GetSize() -1;
    return FindValidObject(false /* backward */);
}

void* HashTableIterator::GetNext()
{
    if (m_lAt+1 >= m_aTable.GetSize())
        return NULL;

    m_lAt++;
    return FindValidObject(true /* forward */);
}

void* HashTableIterator::GetPrev()
{
    if (m_lAt <= 0)
        return NULL;

    m_lAt--;
    return FindValidObject(false /* backward */);
}

void* HashTableIterator::FindValidObject(bool bForward)
// Sucht nach einem vorhandenen Objekt ab der aktuellen
// Position.
//
// pre:  ab inkl. m_lAt soll die Suche beginnen
// post: if not found then
//          if bForward == TRUE then
//              m_lAt == m_aTable.GetSize() -1
//          else
//              m_lAt == 0
//       else
//          m_lAt ist die gefundene Position
{
    void *pObject = m_aTable.GetObjectAt(m_lAt);

    if (pObject != NULL)
        return pObject;

    while (pObject == NULL
       && (bForward ? ((m_lAt+1) < m_aTable.GetSize())
                    :   m_lAt    > 0))
    {
        if (bForward)
            m_lAt++;
        else
            m_lAt--;

        pObject = m_aTable.GetObjectAt(m_lAt);
    }

    return pObject;
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.22); FILE MERGED 2005/09/05 18:39:48 rt 1.2.22.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hashtbl.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:27:55 $
 *
 *  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
 *
 ************************************************************************/

#include "hashtbl.hxx"
#include <string.h>

// -------------------------------------------------------------
// class HashItem
//
class HashItem
{
    enum ETag { TAG_EMPTY, TAG_USED, TAG_DELETED };

    void*   m_pObject;
    ETag    m_Tag;
    char*   m_Key;

public:
    HashItem() { m_Tag = TAG_EMPTY; m_Key = NULL; m_pObject = NULL; }
    ~HashItem() { delete [] m_Key; }

    bool IsDeleted() const
    {   return m_Tag == TAG_DELETED; }

    bool IsEmpty() const
    {   return m_Tag == TAG_DELETED || m_Tag == TAG_EMPTY; }

    bool IsFree() const
    {   return m_Tag == TAG_EMPTY; }

    bool IsUsed() const
    {   return m_Tag == TAG_USED; }

    void Delete()
    { m_Tag = TAG_DELETED; delete [] m_Key; m_Key = new char[ 1 ]; m_Key[ 0 ] = 0; m_pObject = NULL; }

    const char *GetKey() const
    { return m_Key; }

    void* GetObject() const
    { return m_pObject; }

    void SetObject(const char * Key, void *pObject)
    { m_Tag = TAG_USED; delete [] m_Key; m_Key = new char[ strlen( Key ) + 1 ]; strcpy( m_Key, Key ); m_pObject = pObject; }
};

#define MIN(a,b) (a)<(b)?(a):(b)
#define MAX(a,b) (a)>(b)?(a):(b)

// -------------------------------------------------------------
// class HashTable
//

/*static*/ double HashTable::m_defMaxLoadFactor = 0.5;
/*static*/ double HashTable::m_defDefGrowFactor = 2.0;

HashTable::HashTable(unsigned long lSize, bool bOwner, double dMaxLoadFactor, double dGrowFactor)
{
    m_lSize          = lSize;
    m_bOwner         = bOwner;
    m_lElem          = 0;
    m_dMaxLoadFactor = MAX(0.5,MIN(1.0,dMaxLoadFactor));  // 0.5 ... 1.0
    m_dGrowFactor    = MAX(2.0,MIN(5.0,dGrowFactor));     // 1.3 ... 5.0
    m_pData          = new HashItem [lSize];
}

HashTable::~HashTable()
{
    // Wenn die HashTable der Owner der Objecte ist,
    // mssen die Destruktoren separat gerufen werden.
    // Dies geschieht ber die virtuelle Methode OnDeleteObject()
    //
    // Problem: Virtuelle Funktionen sind im Destructor nicht virtuell!!
    //          Der Code mu deshalb ins Macro

    /*
    if (m_bOwner)
    {
        for (ULONG i=0; i<GetSize(); i++)
        {
            void *pObject = GetObjectAt(i);

            if (pObject != NULL)
                OnDeleteObject(pObject());
        }
    }
    */

    // Speicher fr HashItems freigeben
    delete [] m_pData;
}

void* HashTable::GetObjectAt(unsigned long lPos) const
// Gibt Objekt zurck, wenn es eines gibt, sonst NULL;
{
    HashItem *pItem = &m_pData[lPos];

    return pItem->IsUsed() ? pItem->GetObject() : NULL;
}

void HashTable::OnDeleteObject(void*)
{
}

unsigned long HashTable::Hash(const char *Key) const
{
    // Hashfunktion von P.J. Weinberger
    // aus dem "Drachenbuch" von Aho/Sethi/Ullman
    unsigned long i,n;
    unsigned long h = 0;
    unsigned long g = 0;

    for (i=0,n=strlen( Key ); i<n; i++)
    {
        h = (h<<4) + (unsigned long)(unsigned short)Key[i];
        g = h & 0xf0000000;

        if (g != 0)
        {
            h = h ^ (g >> 24);
            h = h ^ g;
        }
    }

    return h % m_lSize;
}

unsigned long HashTable::DHash(const char* Key, unsigned long lOldHash) const
{
    unsigned long lHash = lOldHash;
    unsigned long i,n;

    for (i=0,n=strlen( Key ); i<n; i++)
    {
        lHash *= 256L;
        lHash += (unsigned long)(unsigned short)Key[i];
        lHash %= m_lSize;
    }
    return lHash;
}

unsigned long HashTable::Probe(unsigned long lPos) const
// gibt den Folgewert von lPos zurck
{
    lPos++; if (lPos==m_lSize) lPos=0;
    return lPos;
}

bool HashTable::IsFull() const
{
    return m_lElem>=m_lSize;
}

bool HashTable::Insert(const char * Key, void* pObject)
// pre:  Key ist nicht im Dictionary enthalten, sonst return FALSE
//       Dictionary ist nicht voll, sonst return FALSE
// post: pObject ist unter Key im Dictionary; m_nElem wurde erhht
{
    SmartGrow();

    if (IsFull())
    {
        return false;
    }

    if (FindPos(Key) != NULL )
        return false;

    unsigned long     lPos  = Hash(Key);
    HashItem *pItem = &m_pData[lPos];

    // first hashing
    //
    if (pItem->IsEmpty())
    {
        pItem->SetObject(Key, pObject);
        m_lElem++;

        return true;
    }

    // double hashing
    //
    lPos  = DHash(Key,lPos);
    pItem = &m_pData[lPos];

    if (pItem->IsEmpty())
    {
        pItem->SetObject(Key, pObject);
        m_lElem++;

        return true;
    }

    // linear probing
    //
    do
    {
        lPos  = Probe(lPos);
        pItem = &m_pData[lPos];
    }
    while(!pItem->IsEmpty());

    pItem->SetObject(Key, pObject);
    m_lElem++;
    return true;
}

HashItem* HashTable::FindPos(const char * Key) const
// sucht den Key; gibt Refrenz auf den Eintrag (gefunden)
// oder NULL (nicht gefunden) zurck
//
// pre:  -
// post: -
{
    // first hashing
    //
    unsigned long     lPos  = Hash(Key);
    HashItem *pItem = &m_pData[lPos];

    if (pItem->IsUsed()
    &&  !(strcmp( pItem->GetKey(), Key )))
    {
        return pItem;
    }

    // double hashing
    //
    if (pItem->IsDeleted() || pItem->IsUsed())
    {
        lPos  = DHash(Key,lPos);
        pItem = &m_pData[lPos];

        if (pItem->IsUsed()
        &&  (!strcmp( pItem->GetKey(), Key)))
        {
            return pItem;
        }

        // linear probing
        //
        if (pItem->IsDeleted() || pItem->IsUsed())
        {
            unsigned long n      = 0;
            bool  bFound = false;
            bool  bEnd   = false;

            do
            {
                n++;
                lPos   = Probe(lPos);
                pItem  = &m_pData[lPos];

                bFound =  pItem->IsUsed()
                       && !( strcmp( pItem->GetKey(), Key ));

                bEnd = !(n<m_lSize || pItem->IsFree());
            }
            while(!bFound && !bEnd);

            return bFound ? pItem : NULL;
        }
    }

    // nicht gefunden
    //
    return NULL;
}

void* HashTable::Find(const char *Key) const
// Gibt Verweis des Objektes zurck, das unter Key abgespeichert ist,
// oder NULL wenn nicht vorhanden.
//
// pre:  -
// post: -
{
    HashItem *pItem = FindPos(Key);

    if (pItem != NULL
    && ( !strcmp( pItem->GetKey(), Key )))
        return pItem->GetObject();
    else
        return NULL;
}

void* HashTable::Delete( const char * Key)
// Lscht Objekt, das unter Key abgespeichert ist und gibt Verweis
// darauf zurck.
// Gibt NULL zurck, wenn Key nicht vorhanden ist.
//
// pre:  -
// post: Objekt ist nicht mehr enthalten; m_lElem dekrementiert
//       Wenn die HashTable der Owner ist, wurde das Object gelscht
{
    HashItem *pItem = FindPos(Key);

    if (pItem != NULL
    &&  ( !strcmp( pItem->GetKey(), Key )))
    {
        void* pObject = pItem->GetObject();

        if (m_bOwner)
            OnDeleteObject(pObject);

        pItem->Delete();
        m_lElem--;
        return pObject;
    }
    else
    {
        return NULL;
    }
}

double HashTable::CalcLoadFactor() const
// prozentuale Belegung der Hashtabelle berechnen
{
    return double(m_lElem) / double(m_lSize);
}

void HashTable::SmartGrow()
// Achtung: da die Objekte umkopiert werden, darf die OnDeleteObject-Methode
//          nicht gerufen werden
{
    double dLoadFactor = CalcLoadFactor();

    if (dLoadFactor <= m_dMaxLoadFactor)
        return; // nothing to grow

    unsigned long     lOldSize = m_lSize;              // alte Daten sichern
    HashItem* pOldData = m_pData;

    m_lSize = unsigned long (m_dGrowFactor * m_lSize); // neue Gre
    m_pData = new HashItem[m_lSize];           // neue Daten holen

    // kein Speicher:
    // Zustand "Tabelle voll" wird in Insert abgefangen
    //
    if (m_pData == NULL)
    {
        m_lSize = lOldSize;
        m_pData = pOldData;
        return;
    }

    m_lElem = 0;                               // noch keine neuen Daten

    // Umkopieren der Daten
    //
    for (unsigned long i=0; i<lOldSize; i++)
    {
        HashItem *pItem = &pOldData[i];

        if (pItem->IsUsed())
            Insert(pItem->GetKey(),pItem->GetObject());
    }

    delete [] pOldData;
}

// Iterator ---------------------------------------------------------
//

HashTableIterator::HashTableIterator(HashTable const& aTable)
: m_aTable(aTable)
{
    m_lAt = 0;
}

void* HashTableIterator::GetFirst()
{
    m_lAt = 0;
    return FindValidObject(true /* forward */);
}

void* HashTableIterator::GetLast()
{
    m_lAt = m_aTable.GetSize() -1;
    return FindValidObject(false /* backward */);
}

void* HashTableIterator::GetNext()
{
    if (m_lAt+1 >= m_aTable.GetSize())
        return NULL;

    m_lAt++;
    return FindValidObject(true /* forward */);
}

void* HashTableIterator::GetPrev()
{
    if (m_lAt <= 0)
        return NULL;

    m_lAt--;
    return FindValidObject(false /* backward */);
}

void* HashTableIterator::FindValidObject(bool bForward)
// Sucht nach einem vorhandenen Objekt ab der aktuellen
// Position.
//
// pre:  ab inkl. m_lAt soll die Suche beginnen
// post: if not found then
//          if bForward == TRUE then
//              m_lAt == m_aTable.GetSize() -1
//          else
//              m_lAt == 0
//       else
//          m_lAt ist die gefundene Position
{
    void *pObject = m_aTable.GetObjectAt(m_lAt);

    if (pObject != NULL)
        return pObject;

    while (pObject == NULL
       && (bForward ? ((m_lAt+1) < m_aTable.GetSize())
                    :   m_lAt    > 0))
    {
        if (bForward)
            m_lAt++;
        else
            m_lAt--;

        pObject = m_aTable.GetObjectAt(m_lAt);
    }

    return pObject;
}
<|endoftext|>


<commit_before>#include "bc127.h"

#include <Arduino.h>

// Wraps internal stream port
// Returns: int, number of available bytes
int BC127::available()
{
    return _serialPort->available();
}

// Wraps internal stream read
// Returns int, first byte read or -1 if no data available
int BC127::read()
{
    return _serialPort->read();
}

// Wraps internal stream readString
// Returns: String, the string that was read
String BC127::readString(size_t max)
{
    return _serialPort->readString(max);
}

// Sets internal timeout
void BC127::setTimeout(unsigned long timeout)
{
    _timeout = timeout;
}

// Wraps internal stream print
// Returns: size_t, number of bytes written
size_t BC127::print(char c)
{
    return _serialPort->print(c);
}

// Wraps internal stream print
// Returns: size_t, number of bytes written
size_t BC127::printString(const String &s)
{
    return _serialPort->print(s);
}

// Turns on | off BLE advertising
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::advertise(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");

    return stdCmd("ADVERTISING " + modeStr);
}

// Closes a connection link given by linkid
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::close(int linkid)
{
    String linkStr = linkid < 0 ? String("all") : String(linkid);

    return stdCmd("CLOSE " + linkStr);
}

// Power cycles the device
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::power(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");
    return stdCmd("POWER " + modeStr);
}

// Makes the device discoverable in Classic Mode
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::discoverable(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");

    return stdCmd("DISCOVERABLE " + modeStr);
}

// Retrieves the configuration registers - all or specified by config
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::getConfig(String config)
{
    if (config == "")
        return stdCmd("CONFIG");

    BC127::opResult res = stdCmd("GET " + config);

    if (res)
        _cmdResponse = _cmdResponse.substring(config.length() + 1, _cmdResponse.indexOf(EOL));

    return res;
}

// Enters data mode (not available for BLE in firmware v.5.0)
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::enterDataMode()
{
    return stdCmd("ENTER_DATA");
}

// Exits from data mode
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::exitDataMode(int guardDelay)
{
    delay(guardDelay);

    _serialPort->print("$$$$");
    _serialPort->flush();

    return waitResponse();
}

// Sends a string via the default connection
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::send(String str)
{
    return stdCmd("SEND " + str);
}

// Retrieves the device connection status
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::status()
{
    return stdCmd("STATUS");
}

// Resets the device to default configuration
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse contains the data on SUCCESS
BC127::opResult BC127::reset()
{
    return stdCmd("RESET");
}

// Restores a device to factory settings
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::restore()
{
    return stdCmd("RESTORE");
}

// Writes the current configuration registers to non-volatile memory
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::writeConfig()
{
    return stdCmd("WRITE");
}

// Helper function for generic command execution
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::stdCmd(String command)
{
    knownStart(); // Clear the serial buffer in the module and the Arduino.

    // maybe future me can figure out how to send bytes vs. chars
    // char tmp[150];
    // String(command + EOC).toCharArray(tmp, 150);
    // _serialPort->write(tmp, 150);
    _serialPort->print(command + EOC);
    _serialPort->flush();

    return waitResponse();
}

// Sets a given configuration register with param value
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::setConfig(String config, String param)
{
    return stdCmd("SET " + config + "=" + param);
}

// Retrieves the firmware version information of the device
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::version()
{
    return stdCmd("VERSION");
}

// Retrieves the embedded help menu
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::help()
{
    return stdCmd("HELP");
}

// Returns _cmdResponse string from previous command
// Returns: _cmdResponse
String BC127::getCmdResponse()
{
    return _cmdResponse;
}

// Create a known state for the module to start from. If a partial command is
//  already in the module's buffer, we can purge it by sending an EOL to the
//  the module. If not, we'll just get an error.
BC127::opResult BC127::knownStart()
{
    String buffer = "";

    _serialPort->print(EOC);
    _serialPort->flush();

    // We're going to use the internal timer to track the elapsed time since we
    //  issued the reset. Bog-standard Arduino stuff.
    unsigned long startTime = millis();

    // This is our timeout loop. We're going to give our module 100ms to come up
    //  with a new character, and return with a timeout failure otherwise.
    while (buffer.endsWith(EOL) != true)
    {
        // Purge the serial data received from the module, along with any data in
        //  the buffer at the time this command was sent.
        if (_serialPort->available() > 0)
        {
            buffer.concat(char(_serialPort->read()));
            startTime = millis();
        }

        if ((startTime + _timeout) < millis())
            return TIMEOUT_ERROR;
    }

    if (buffer.startsWith("ERR"))
        return SUCCESS;
    else
        return SUCCESS;
}

// Grab an EOL-delimited string of output from the serial line
// Returns: SUCCES | MODULE_ERROR | TIMEOUT_ERROR
//          msg will contain the string on SUCCESS
BC127::opResult BC127::recv(String *msg)
{
    if (!msg) // don't do this
        return MODULE_ERROR;

    // start our timer
    unsigned long startTime = millis();

    // as long as we have time
    while ((startTime + _timeout) > millis())
    {
        // grab a character and append it to the current msg
        if (_serialPort->available() > 0)
        {
            msg->concat((char)_serialPort->read());
        }

        // we've reached the EOL sequence
        if (msg->endsWith(EOL))
        {
            return SUCCESS;
        }
    }

    return TIMEOUT_ERROR;
}

// Convenience method to handle the raw internal stream
// Returns: _serialPort
Stream *BC127::getSerial()
{
    return _serialPort;
}

// Timeout wait for the response from a command
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::waitResponse(int time)
{
    // some output has multiple lines
    String line = String("");

    // decide how long we're willing to wait
    int timeout = time > 0 ? time : _timeout;

    // get our start time
    unsigned long startTime = millis();

    // reset previous command response
    _cmdResponse = "";

    // as long as we have time
    while ((startTime + timeout) > millis())
    {
        // grab a character and append to current line and command response
        if (_serialPort->available() > 0)
        {
            char temp = _serialPort->read();
            line.concat(temp);
            _cmdResponse.concat(temp);
        }

        // we've reached the end of a line
        if (line.endsWith(EOL))
        {
            // Is this the end of the command response?
            if (line.startsWith("OK") || line.startsWith("Ready"))
            {
                return SUCCESS;
            }
            else if (line.startsWith("ERROR"))
            {
                return MODULE_ERROR;
            }

            // move on to next line
            line = "";
        }
    }

    return TIMEOUT_ERROR; // ran out of time
}<commit_msg>BC127 library: the BC127 adds an EOL sequence to each message; we should strip this off and not pass it along to the caller, since it wasn't part of the received payload.<commit_after>#include "bc127.h"

#include <Arduino.h>

// Wraps internal stream port
// Returns: int, number of available bytes
int BC127::available()
{
    return _serialPort->available();
}

// Wraps internal stream read
// Returns int, first byte read or -1 if no data available
int BC127::read()
{
    return _serialPort->read();
}

// Wraps internal stream readString
// Returns: String, the string that was read
String BC127::readString(size_t max)
{
    return _serialPort->readString(max);
}

// Sets internal timeout
void BC127::setTimeout(unsigned long timeout)
{
    _timeout = timeout;
}

// Wraps internal stream print
// Returns: size_t, number of bytes written
size_t BC127::print(char c)
{
    return _serialPort->print(c);
}

// Wraps internal stream print
// Returns: size_t, number of bytes written
size_t BC127::printString(const String &s)
{
    return _serialPort->print(s);
}

// Turns on | off BLE advertising
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::advertise(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");

    return stdCmd("ADVERTISING " + modeStr);
}

// Closes a connection link given by linkid
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::close(int linkid)
{
    String linkStr = linkid < 0 ? String("all") : String(linkid);

    return stdCmd("CLOSE " + linkStr);
}

// Power cycles the device
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::power(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");
    return stdCmd("POWER " + modeStr);
}

// Makes the device discoverable in Classic Mode
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::discoverable(bool mode)
{
    String modeStr = mode ? String("ON") : String("OFF");

    return stdCmd("DISCOVERABLE " + modeStr);
}

// Retrieves the configuration registers - all or specified by config
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::getConfig(String config)
{
    if (config == "")
        return stdCmd("CONFIG");

    BC127::opResult res = stdCmd("GET " + config);

    if (res)
        _cmdResponse = _cmdResponse.substring(config.length() + 1, _cmdResponse.indexOf(EOL));

    return res;
}

// Enters data mode (not available for BLE in firmware v.5.0)
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::enterDataMode()
{
    return stdCmd("ENTER_DATA");
}

// Exits from data mode
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::exitDataMode(int guardDelay)
{
    delay(guardDelay);

    _serialPort->print("$$$$");
    _serialPort->flush();

    return waitResponse();
}

// Sends a string via the default connection
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::send(String str)
{
    return stdCmd("SEND " + str);
}

// Retrieves the device connection status
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::status()
{
    return stdCmd("STATUS");
}

// Resets the device to default configuration
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse contains the data on SUCCESS
BC127::opResult BC127::reset()
{
    return stdCmd("RESET");
}

// Restores a device to factory settings
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::restore()
{
    return stdCmd("RESTORE");
}

// Writes the current configuration registers to non-volatile memory
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::writeConfig()
{
    return stdCmd("WRITE");
}

// Helper function for generic command execution
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::stdCmd(String command)
{
    knownStart(); // Clear the serial buffer in the module and the Arduino.

    // maybe future me can figure out how to send bytes vs. chars
    // char tmp[150];
    // String(command + EOC).toCharArray(tmp, 150);
    // _serialPort->write(tmp, 150);
    _serialPort->print(command + EOC);
    _serialPort->flush();

    return waitResponse();
}

// Sets a given configuration register with param value
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
BC127::opResult BC127::setConfig(String config, String param)
{
    return stdCmd("SET " + config + "=" + param);
}

// Retrieves the firmware version information of the device
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::version()
{
    return stdCmd("VERSION");
}

// Retrieves the embedded help menu
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::help()
{
    return stdCmd("HELP");
}

// Returns _cmdResponse string from previous command
// Returns: _cmdResponse
String BC127::getCmdResponse()
{
    return _cmdResponse;
}

// Create a known state for the module to start from. If a partial command is
//  already in the module's buffer, we can purge it by sending an EOL to the
//  the module. If not, we'll just get an error.
BC127::opResult BC127::knownStart()
{
    String buffer = "";

    _serialPort->print(EOC);
    _serialPort->flush();

    // We're going to use the internal timer to track the elapsed time since we
    //  issued the reset. Bog-standard Arduino stuff.
    unsigned long startTime = millis();

    // This is our timeout loop. We're going to give our module 100ms to come up
    //  with a new character, and return with a timeout failure otherwise.
    while (buffer.endsWith(EOL) != true)
    {
        // Purge the serial data received from the module, along with any data in
        //  the buffer at the time this command was sent.
        if (_serialPort->available() > 0)
        {
            buffer.concat(char(_serialPort->read()));
            startTime = millis();
        }

        if ((startTime + _timeout) < millis())
            return TIMEOUT_ERROR;
    }

    if (buffer.startsWith("ERR"))
        return SUCCESS;
    else
        return SUCCESS;
}

// Grab an EOL-delimited string of output from the serial line
// Returns: SUCCES | MODULE_ERROR | TIMEOUT_ERROR
//          msg will contain the string on SUCCESS
BC127::opResult BC127::recv(String *msg)
{
    if (!msg) // don't do this
        return MODULE_ERROR;

    // start our timer
    unsigned long startTime = millis();

    // as long as we have time
    while ((startTime + _timeout) > millis())
    {
        // grab a character and append it to the current msg
        if (_serialPort->available() > 0)
        {
            msg->concat((char)_serialPort->read());
        }

        // we've reached the EOL sequence
        if (msg->endsWith(EOL))
        {
            // Lop off the EOL, since it is added by the BC127 and is not part of the characteristic payload
            *msg = msg->substring(0,msg->length()-2);
            return SUCCESS;
        }
    }

    return TIMEOUT_ERROR;
}

// Convenience method to handle the raw internal stream
// Returns: _serialPort
Stream *BC127::getSerial()
{
    return _serialPort;
}

// Timeout wait for the response from a command
// Returns: SUCCESS | MODULE_ERROR | TIMEOUT_ERROR
//          _cmdResponse will contain the data on SUCCESS
BC127::opResult BC127::waitResponse(int time)
{
    // some output has multiple lines
    String line = String("");

    // decide how long we're willing to wait
    int timeout = time > 0 ? time : _timeout;

    // get our start time
    unsigned long startTime = millis();

    // reset previous command response
    _cmdResponse = "";

    // as long as we have time
    while ((startTime + timeout) > millis())
    {
        // grab a character and append to current line and command response
        if (_serialPort->available() > 0)
        {
            char temp = _serialPort->read();
            line.concat(temp);
            _cmdResponse.concat(temp);
        }

        // we've reached the end of a line
        if (line.endsWith(EOL))
        {
            // Is this the end of the command response?
            if (line.startsWith("OK") || line.startsWith("Ready"))
            {
                return SUCCESS;
            }
            else if (line.startsWith("ERROR"))
            {
                return MODULE_ERROR;
            }

            // move on to next line
            line = "";
        }
    }

    return TIMEOUT_ERROR; // ran out of time
}<|endoftext|>


<commit_before>/*
Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

#include <stdio.h>

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

void print_list(ListNode *list) {
	for ( ; list != NULL; list = list->next) {
		printf("%d->", list->val);
	}
	printf("NULL\n");
}

// 1->2->3->4->5->NULL
// 1->2->4->5->5->NULL
//		3
class Solution {
public:
	void deleteNode(ListNode* node) {
		ListNode* p = node;

		int step = 0;
		for (; p->next->next != NULL; p = p->next) {
			step++;
			p->val = p->next->val;
		}
		if (step < 2) {
			p->val = p->next->val;
			p->next = NULL;
			return;
		}

		p->val = p->next->val;
		p->next = NULL;

		return;
    }
};

int main() {
	ListNode l1(1), l2(2), l3(3);
	ListNode l4(4), l5(5), l6(6), l7(7), l8(8), l9(9), l10(10), l11(11), l12(12), l13(13);
	ListNode n1(0), n2(0), n3(0), n4(1);
	l1.next = &l2;
	l2.next = &l3;

	l4.next = &l5;
	l5.next = &l6;
	l6.next = &l7;
	l7.next = &l8;
	l8.next = &l9;
	l9.next = &l10;
	l10.next = &l11;
	l11.next = &l12;
	l12.next = &l13;

	n1.next = &n2;
	n2.next = &n3;
	n3.next = &n4;

	printf("Before deleteing:\n");
	print_list(&n1);

	Solution s;
	s.deleteNode(&n1);
	printf("After deleteing:\n");
	print_list(&n1);

	return 0;
}
<commit_msg>task237 accepted<commit_after>/*
Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

#include <stdio.h>

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

void print_list(ListNode *list) {
	for ( ; list != NULL; list = list->next) {
		printf("%d->", list->val);
	}
	printf("NULL\n");
}

// 1->2->3->4->5->NULL
// 1->2->4->5->5->NULL
//		3
class Solution {
public:
	void deleteNode(ListNode* node) {
		ListNode* p = node;
		ListNode* q = node;

		for (; p->next != NULL; q = p, p = p->next) {
			p->val = p->next->val;
		}
		q->val = p->val;
		q->next = NULL;

		return;
    }
};

int main() {
	ListNode l1(1), l2(2), l3(3);
	ListNode l4(4), l5(5), l6(6), l7(7), l8(8), l9(9), l10(10), l11(11), l12(12), l13(13);
	ListNode n1(0), n2(0), n3(0), n4(1);
	l1.next = &l2;
	l2.next = &l3;

	l4.next = &l5;
	l5.next = &l6;
	l6.next = &l7;
	l7.next = &l8;
	l8.next = &l9;
	l9.next = &l10;
	l10.next = &l11;
	l11.next = &l12;
	l12.next = &l13;

	n1.next = &n2;
	n2.next = &n3;
	n3.next = &n4;

	printf("Before deleteing:\n");
	print_list(&n1);

	Solution s;
	s.deleteNode(&n1);
	printf("After deleteing:\n");
	print_list(&n1);

	return 0;
}
<|endoftext|>