<commit_before>/*
 * Copyright 2015 Aldebaran
 *
 * 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 "memory_list.hpp"

namespace alros {

namespace converter {

MemoryListConverter::MemoryListConverter(const std::vector<std::string>& key_list, const std::string &name, const float &frequency, const qi::SessionPtr &session):
    BaseConverter(name, frequency, session),
    p_memory_(session->service("ALMemory")),
    _key_list(key_list)
{}

void MemoryListConverter::reset(){

}

void MemoryListConverter::callAll(const std::vector<message_actions::MessageAction> &actions){
  // Get inertial data
  AL::ALValue memData = p_memory_.call<AL::ALValue>("getListData", _key_list);
  // Reset message
  _msg = naoqi_msgs::MemoryList();
  for(int i=0; i<memData.getSize(); i++){
    if(memData[i].isFloat())
    {
      naoqi_msgs::MemoryPairFloat tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i];
      _msg.floats.push_back(tmp_msg);
    }
    else if(memData[i].isString())
    {
      naoqi_msgs::MemoryPairString tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i].toString();
      _msg.strings.push_back(tmp_msg);
    }
    else if(memData[i].isInt())
    {
      naoqi_msgs::MemoryPairInt tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i];
      _msg.ints.push_back(tmp_msg);
    }
  }

  for_each( message_actions::MessageAction action, actions )
  {
    callbacks_[action]( _msg);
  }
}

void MemoryListConverter::registerCallback( const message_actions::MessageAction action, Callback_t cb )
{
  callbacks_[action] = cb;
}

}

}
<commit_msg>Accept bool ALValue (convert them in Int)<commit_after>/*
 * Copyright 2015 Aldebaran
 *
 * 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 "memory_list.hpp"

namespace alros {

namespace converter {

MemoryListConverter::MemoryListConverter(const std::vector<std::string>& key_list, const std::string &name, const float &frequency, const qi::SessionPtr &session):
    BaseConverter(name, frequency, session),
    p_memory_(session->service("ALMemory")),
    _key_list(key_list)
{}

void MemoryListConverter::reset(){

}

void MemoryListConverter::callAll(const std::vector<message_actions::MessageAction> &actions){
  // Get inertial data
  AL::ALValue memData = p_memory_.call<AL::ALValue>("getListData", _key_list);
  // Reset message
  _msg = naoqi_msgs::MemoryList();
  for(int i=0; i<memData.getSize(); i++){
    if(memData[i].isFloat())
    {
      naoqi_msgs::MemoryPairFloat tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i];
      _msg.floats.push_back(tmp_msg);
    }
    else if(memData[i].isString())
    {
      naoqi_msgs::MemoryPairString tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i].toString();
      _msg.strings.push_back(tmp_msg);
    }
    else if(memData[i].isInt())
    {
      naoqi_msgs::MemoryPairInt tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      tmp_msg.data = memData[i];
      _msg.ints.push_back(tmp_msg);
    }
    else if(memData[i].isBool())
    {
      naoqi_msgs::MemoryPairInt tmp_msg;
      tmp_msg.memoryKey = _key_list[i];
      bool value = memData[i];
      tmp_msg.data = (int) value;
      _msg.ints.push_back(tmp_msg);
    }
  }

  for_each( message_actions::MessageAction action, actions )
  {
    callbacks_[action]( _msg);
  }
}

void MemoryListConverter::registerCallback( const message_actions::MessageAction action, Callback_t cb )
{
  callbacks_[action] = cb;
}

}

}
<|endoftext|>


<commit_before>/*
  This file is part of the kblog library.

  Copyright (c) 2006-2007 Christian Weilbach <christian_weilbach@web.de>
  Copyright (c) 2007 Mike Arthur <mike@mikearthur.co.uk>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "blogposting.h"
#include "blogposting_p.h"

#include "blog.h"

#include <KDateTime>
#include <KUrl>
#include <kcal/journal.h>

#include <QStringList>

namespace KBlog {

BlogPosting::BlogPosting( const KBlog::BlogPosting& posting ):
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr=this;
  d_ptr->mPrivate=posting.isPrivate();
  d_ptr->mPostingId=posting.postingId();
  d_ptr->mTitle=posting.title();
  d_ptr->mContent=posting.content();
  d_ptr->mCategories=posting.categories();
  d_ptr->mError=posting.error();
  d_ptr->mJournalId=posting.journalId();
  d_ptr->mStatus=posting.status();
  d_ptr->mCreationDateTime=posting.creationDateTime();
  d_ptr->mModificationDateTime=posting.modificationDateTime();
}

BlogPosting::BlogPosting( const QString &postingId ) :
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr = this;
  d_ptr->mPrivate = false;
  d_ptr->mPostingId = postingId;
  d_ptr->mStatus = New;
}

BlogPosting::BlogPosting( const KCal::Journal &journal ) :
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr = this;
  d_ptr->mPrivate = false;
  d_ptr->mPostingId = journal.customProperty( "KBLOG", "ID" );
  d_ptr->mJournalId = journal.uid();
  d_ptr->mStatus = New;
  d_ptr->mTitle = journal.summary();
  d_ptr->mContent = journal.description();
  d_ptr->mCategories = journal.categories();
  d_ptr->mCreationDateTime = journal.dtStart();
}

// BlogPosting::BlogPosting( const KCal::Journal &journal, BlogPostingPrivate &dd )
//   : d_ptr( &dd )
// {
//   d_ptr->q_ptr = this;
//   d_ptr->mPrivate = false;
//   d_ptr->mPostingId = journal.customProperty( "KBLOG", "ID" );
//   d_ptr->mJournalId = journal.uid();
//   d_ptr->mStatus = New;
//   d_ptr->mTitle = journal.summary();
//   d_ptr->mContent = journal.description();
//   d_ptr->mCategories = journal.categories();
//   d_ptr->mCreationDateTime = journal.dtStart();
// }

BlogPosting::~BlogPosting()
{
  delete d_ptr;
}

KCal::Journal* BlogPosting::journal( const Blog &blog ) const
{
  QString url = blog.url().url();
  QString username = blog.username();
  QString blogId = blog.blogId();
  // Generate unique ID. Should be unique enough...
  QString id = "kblog-" + url + '-' + blogId  + '-' + username +
      '-' + d_ptr->mPostingId;
  KCal::Journal *journal = new KCal::Journal();
  journal->setUid( id );
  journal->setSummary( d_ptr->mTitle );
  journal->setCategories( d_ptr->mCategories );
  //journal->setDescription( d_ptr->mContent, true );
  journal->setDtStart( d_ptr->mCreationDateTime );
  journal->setCustomProperty( "KBLOG", "URL", url );
  journal->setCustomProperty( "KBLOG", "USER", blog.username() );
  journal->setCustomProperty( "KBLOG", "BLOG", blogId );
  journal->setCustomProperty( "KBLOG", "ID", d_ptr->mPostingId );
  return journal;
}

QString BlogPosting::journalId() const
{
  return d_ptr->mJournalId;
}

bool BlogPosting::isPrivate() const
{
  return d_ptr->mPrivate;
}

void BlogPosting::setPrivate( bool privatePosting )
{
  d_ptr->mPrivate = privatePosting;
}

QString BlogPosting::postingId() const
{
  return d_ptr->mPostingId;
}

void BlogPosting::setPostingId( const QString &postingId )
{
  d_ptr->mPostingId = postingId;
}

QString BlogPosting::title() const
{
  return d_ptr->mTitle;
}

void BlogPosting::setTitle( const QString &title )
{
  d_ptr->mTitle = title;
}

QString BlogPosting::content() const
{
  return d_ptr->mContent;
}

void BlogPosting::setContent( const QString &content )
{
  d_ptr->mContent = content;
}

// QString BlogPosting::abbreviatedContent() const
// {
//   //TODO
//   return 0;
// }
//
// void BlogPosting::setAbbreviatedContent( const QString &abbreviatedContent )
// {
//   Q_UNUSED( abbreviatedContent );
//   //TODO
// }

KUrl BlogPosting::link() const
{
  return d_ptr->mLink;
}

void BlogPosting::setLink( const KUrl &link ) const
{
  d_ptr->mLink = link;
}

KUrl BlogPosting::permaLink() const
{
  return d_ptr->mPermaLink;
}

void BlogPosting::setPermaLink( const KUrl &permalink ) const
{
  d_ptr->mPermaLink = permalink;
}

bool BlogPosting::isCommentAllowed() const
{
  return d_ptr->mCommentAllowed;
}

void BlogPosting::setCommentAllowed( bool commentAllowed )
{
  d_ptr->mCommentAllowed = commentAllowed;
}

bool BlogPosting::isTrackBackAllowed() const
{
  return d_ptr->mCommentAllowed;
}

void BlogPosting::setTrackBackAllowed ( bool allowTrackBacks )
{
  d_ptr->mTrackBackAllowed = allowTrackBacks;
}

QString BlogPosting::summary() const
{
  return d_ptr->mSummary;
}

void BlogPosting::setSummary( const QString &summary )
{
  d_ptr->mSummary = summary;
}

QStringList BlogPosting::tags() const
{
  return d_ptr->mTags;
}

void BlogPosting::setTags( const QStringList &tags )
{
  d_ptr->mTags = tags;
}

// QList<KUrl> BlogPosting::trackBackUrls() const
// {
//   //TODO
//   return QList<KUrl>();
// }
//
// void BlogPosting::setTrackBackUrls( const QList<KUrl> &trackBackUrls )
// {
//   Q_UNUSED( trackBackUrls );
//   //TODO
// }

QString BlogPosting::mood() const
{
  //TODO
  return QString();
}

void BlogPosting::setMood( const QString &mood )
{
  Q_UNUSED( mood );
  //TODO
}

QString BlogPosting::music() const
{
  //TODO
  return QString();
}

void BlogPosting::setMusic( const QString &music )
{
  Q_UNUSED( music );
  //TODO
}

QStringList BlogPosting::categories() const
{
  return d_ptr->mCategories;
}

void BlogPosting::setCategories( const QStringList &categories )
{
  d_ptr->mCategories = categories;
}

KDateTime BlogPosting::creationDateTime() const
{
  return d_ptr->mCreationDateTime;
}

void BlogPosting::setCreationDateTime( const KDateTime &datetime )
{
  d_ptr->mCreationDateTime = datetime;
}

KDateTime BlogPosting::modificationDateTime() const
{
  return d_ptr->mModificationDateTime;
}

void BlogPosting::setModificationDateTime( const KDateTime &datetime )
{
  d_ptr->mModificationDateTime = datetime;
}

BlogPosting::Status BlogPosting::status() const
{
  return d_ptr->mStatus;
}

void BlogPosting::setStatus( BlogPosting::Status status )
{
  d_ptr->mStatus = status;
//   emit statusChanged( status );
}

QString BlogPosting::error() const
{
  return d_ptr->mError;
}

void BlogPosting::setError( const QString &error )
{
  d_ptr->mError = error;
}

BlogPosting& BlogPosting::operator=(const BlogPosting &posting)
{
  *this = BlogPosting ( posting );
  return *this;
}

} // namespace KBlog

<commit_msg>I apologize, i didn't want to comment this line<commit_after>/*
  This file is part of the kblog library.

  Copyright (c) 2006-2007 Christian Weilbach <christian_weilbach@web.de>
  Copyright (c) 2007 Mike Arthur <mike@mikearthur.co.uk>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "blogposting.h"
#include "blogposting_p.h"

#include "blog.h"

#include <KDateTime>
#include <KUrl>
#include <kcal/journal.h>

#include <QStringList>

namespace KBlog {

BlogPosting::BlogPosting( const KBlog::BlogPosting& posting ):
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr=this;
  d_ptr->mPrivate=posting.isPrivate();
  d_ptr->mPostingId=posting.postingId();
  d_ptr->mTitle=posting.title();
  d_ptr->mContent=posting.content();
  d_ptr->mCategories=posting.categories();
  d_ptr->mError=posting.error();
  d_ptr->mJournalId=posting.journalId();
  d_ptr->mStatus=posting.status();
  d_ptr->mCreationDateTime=posting.creationDateTime();
  d_ptr->mModificationDateTime=posting.modificationDateTime();
}

BlogPosting::BlogPosting( const QString &postingId ) :
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr = this;
  d_ptr->mPrivate = false;
  d_ptr->mPostingId = postingId;
  d_ptr->mStatus = New;
}

BlogPosting::BlogPosting( const KCal::Journal &journal ) :
    d_ptr( new BlogPostingPrivate )
{
  d_ptr->q_ptr = this;
  d_ptr->mPrivate = false;
  d_ptr->mPostingId = journal.customProperty( "KBLOG", "ID" );
  d_ptr->mJournalId = journal.uid();
  d_ptr->mStatus = New;
  d_ptr->mTitle = journal.summary();
  d_ptr->mContent = journal.description();
  d_ptr->mCategories = journal.categories();
  d_ptr->mCreationDateTime = journal.dtStart();
}

// BlogPosting::BlogPosting( const KCal::Journal &journal, BlogPostingPrivate &dd )
//   : d_ptr( &dd )
// {
//   d_ptr->q_ptr = this;
//   d_ptr->mPrivate = false;
//   d_ptr->mPostingId = journal.customProperty( "KBLOG", "ID" );
//   d_ptr->mJournalId = journal.uid();
//   d_ptr->mStatus = New;
//   d_ptr->mTitle = journal.summary();
//   d_ptr->mContent = journal.description();
//   d_ptr->mCategories = journal.categories();
//   d_ptr->mCreationDateTime = journal.dtStart();
// }

BlogPosting::~BlogPosting()
{
  delete d_ptr;
}

KCal::Journal* BlogPosting::journal( const Blog &blog ) const
{
  QString url = blog.url().url();
  QString username = blog.username();
  QString blogId = blog.blogId();
  // Generate unique ID. Should be unique enough...
  QString id = "kblog-" + url + '-' + blogId  + '-' + username +
      '-' + d_ptr->mPostingId;
  KCal::Journal *journal = new KCal::Journal();
  journal->setUid( id );
  journal->setSummary( d_ptr->mTitle );
  journal->setCategories( d_ptr->mCategories );
  journal->setDescription( d_ptr->mContent, true );
  journal->setDtStart( d_ptr->mCreationDateTime );
  journal->setCustomProperty( "KBLOG", "URL", url );
  journal->setCustomProperty( "KBLOG", "USER", blog.username() );
  journal->setCustomProperty( "KBLOG", "BLOG", blogId );
  journal->setCustomProperty( "KBLOG", "ID", d_ptr->mPostingId );
  return journal;
}

QString BlogPosting::journalId() const
{
  return d_ptr->mJournalId;
}

bool BlogPosting::isPrivate() const
{
  return d_ptr->mPrivate;
}

void BlogPosting::setPrivate( bool privatePosting )
{
  d_ptr->mPrivate = privatePosting;
}

QString BlogPosting::postingId() const
{
  return d_ptr->mPostingId;
}

void BlogPosting::setPostingId( const QString &postingId )
{
  d_ptr->mPostingId = postingId;
}

QString BlogPosting::title() const
{
  return d_ptr->mTitle;
}

void BlogPosting::setTitle( const QString &title )
{
  d_ptr->mTitle = title;
}

QString BlogPosting::content() const
{
  return d_ptr->mContent;
}

void BlogPosting::setContent( const QString &content )
{
  d_ptr->mContent = content;
}

// QString BlogPosting::abbreviatedContent() const
// {
//   //TODO
//   return 0;
// }
//
// void BlogPosting::setAbbreviatedContent( const QString &abbreviatedContent )
// {
//   Q_UNUSED( abbreviatedContent );
//   //TODO
// }

KUrl BlogPosting::link() const
{
  return d_ptr->mLink;
}

void BlogPosting::setLink( const KUrl &link ) const
{
  d_ptr->mLink = link;
}

KUrl BlogPosting::permaLink() const
{
  return d_ptr->mPermaLink;
}

void BlogPosting::setPermaLink( const KUrl &permalink ) const
{
  d_ptr->mPermaLink = permalink;
}

bool BlogPosting::isCommentAllowed() const
{
  return d_ptr->mCommentAllowed;
}

void BlogPosting::setCommentAllowed( bool commentAllowed )
{
  d_ptr->mCommentAllowed = commentAllowed;
}

bool BlogPosting::isTrackBackAllowed() const
{
  return d_ptr->mCommentAllowed;
}

void BlogPosting::setTrackBackAllowed ( bool allowTrackBacks )
{
  d_ptr->mTrackBackAllowed = allowTrackBacks;
}

QString BlogPosting::summary() const
{
  return d_ptr->mSummary;
}

void BlogPosting::setSummary( const QString &summary )
{
  d_ptr->mSummary = summary;
}

QStringList BlogPosting::tags() const
{
  return d_ptr->mTags;
}

void BlogPosting::setTags( const QStringList &tags )
{
  d_ptr->mTags = tags;
}

// QList<KUrl> BlogPosting::trackBackUrls() const
// {
//   //TODO
//   return QList<KUrl>();
// }
//
// void BlogPosting::setTrackBackUrls( const QList<KUrl> &trackBackUrls )
// {
//   Q_UNUSED( trackBackUrls );
//   //TODO
// }

QString BlogPosting::mood() const
{
  //TODO
  return QString();
}

void BlogPosting::setMood( const QString &mood )
{
  Q_UNUSED( mood );
  //TODO
}

QString BlogPosting::music() const
{
  //TODO
  return QString();
}

void BlogPosting::setMusic( const QString &music )
{
  Q_UNUSED( music );
  //TODO
}

QStringList BlogPosting::categories() const
{
  return d_ptr->mCategories;
}

void BlogPosting::setCategories( const QStringList &categories )
{
  d_ptr->mCategories = categories;
}

KDateTime BlogPosting::creationDateTime() const
{
  return d_ptr->mCreationDateTime;
}

void BlogPosting::setCreationDateTime( const KDateTime &datetime )
{
  d_ptr->mCreationDateTime = datetime;
}

KDateTime BlogPosting::modificationDateTime() const
{
  return d_ptr->mModificationDateTime;
}

void BlogPosting::setModificationDateTime( const KDateTime &datetime )
{
  d_ptr->mModificationDateTime = datetime;
}

BlogPosting::Status BlogPosting::status() const
{
  return d_ptr->mStatus;
}

void BlogPosting::setStatus( BlogPosting::Status status )
{
  d_ptr->mStatus = status;
//   emit statusChanged( status );
}

QString BlogPosting::error() const
{
  return d_ptr->mError;
}

void BlogPosting::setError( const QString &error )
{
  d_ptr->mError = error;
}

BlogPosting& BlogPosting::operator=(const BlogPosting &posting)
{
  *this = BlogPosting ( posting );
  return *this;
}

} // namespace KBlog

<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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 <grpc/support/port_platform.h>

#if defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
    !defined(GPR_CUSTOM_SYNC)

#include <errno.h>
#include <time.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>

#include "src/core/lib/profiling/timers.h"

#ifdef GPR_LOW_LEVEL_COUNTERS
gpr_atm gpr_mu_locks = 0;
gpr_atm gpr_counter_atm_cas = 0;
gpr_atm gpr_counter_atm_add = 0;
#endif

void gpr_mu_init(gpr_mu* mu) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0);
  mu->leak_checker = static_cast<int*>(malloc(sizeof(*mu->leak_checker)));
  GPR_ASSERT(mu->leak_checker != nullptr);
#else
  GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0);
#endif
}

void gpr_mu_destroy(gpr_mu* mu) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0);
  free(mu->leak_checker);
#else
  GPR_ASSERT(pthread_mutex_destroy(mu) == 0);
#endif
}

void gpr_mu_lock(gpr_mu* mu) {
#ifdef GPR_LOW_LEVEL_COUNTERS
  GPR_ATM_INC_COUNTER(gpr_mu_locks);
#endif
  GPR_TIMER_SCOPE("gpr_mu_lock", 0);
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0);
#else
  GPR_ASSERT(pthread_mutex_lock(mu) == 0);
#endif
}

void gpr_mu_unlock(gpr_mu* mu) {
  GPR_TIMER_SCOPE("gpr_mu_unlock", 0);
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0);
#else
  GPR_ASSERT(pthread_mutex_unlock(mu) == 0);
#endif
}

int gpr_mu_trylock(gpr_mu* mu) {
  GPR_TIMER_SCOPE("gpr_mu_trylock", 0);
  int err = 0;
#ifdef GRPC_ASAN_ENABLED
  err = pthread_mutex_trylock(&mu->mutex);
#else
  err = pthread_mutex_trylock(mu);
#endif
  GPR_ASSERT(err == 0 || err == EBUSY);
  return err == 0;
}

/*----------------------------------------*/

void gpr_cv_init(gpr_cv* cv) {
  pthread_condattr_t attr;
  GPR_ASSERT(pthread_condattr_init(&attr) == 0);
#if GPR_LINUX
  GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0);
#endif  // GPR_LINUX

#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0);
  cv->leak_checker = static_cast<int*>(malloc(sizeof(*cv->leak_checker)));
  GPR_ASSERT(cv->leak_checker != nullptr);
#else
  GPR_ASSERT(pthread_cond_init(cv, &attr) == 0);
#endif
}

void gpr_cv_destroy(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0);
  free(cv->leak_checker);
#else
  GPR_ASSERT(pthread_cond_destroy(cv) == 0);
#endif
}

int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
  int err = 0;
  if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
      0) {
#ifdef GRPC_ASAN_ENABLED
    err = pthread_cond_wait(&cv->cond_var, &mu->mutex);
#else
    err = pthread_cond_wait(cv, mu);
#endif
  } else {
    struct timespec abs_deadline_ts;
#if GPR_LINUX
    abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC);
#else
    abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
#endif  // GPR_LINUX
    abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
    abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
#ifdef GRPC_ASAN_ENABLED
    err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts);
#else
    err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts);
#endif
  }
  GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN);
  return err == ETIMEDOUT;
}

void gpr_cv_signal(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0);
#else
  GPR_ASSERT(pthread_cond_signal(cv) == 0);
#endif
}

void gpr_cv_broadcast(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0);
#else
  GPR_ASSERT(pthread_cond_broadcast(cv) == 0);
#endif
}

/*----------------------------------------*/

void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
  GPR_ASSERT(pthread_once(once, init_function) == 0);
}

#endif /* defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
          !defined(GPR_CUSTOM_SYNC) */
<commit_msg>Look at now before sleeping (#28996)<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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 <grpc/support/port_platform.h>

#if defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
    !defined(GPR_CUSTOM_SYNC)

#include <errno.h>
#include <time.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>

#include "src/core/lib/profiling/timers.h"

#ifdef GPR_LOW_LEVEL_COUNTERS
gpr_atm gpr_mu_locks = 0;
gpr_atm gpr_counter_atm_cas = 0;
gpr_atm gpr_counter_atm_add = 0;
#endif

void gpr_mu_init(gpr_mu* mu) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0);
  mu->leak_checker = static_cast<int*>(malloc(sizeof(*mu->leak_checker)));
  GPR_ASSERT(mu->leak_checker != nullptr);
#else
  GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0);
#endif
}

void gpr_mu_destroy(gpr_mu* mu) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0);
  free(mu->leak_checker);
#else
  GPR_ASSERT(pthread_mutex_destroy(mu) == 0);
#endif
}

void gpr_mu_lock(gpr_mu* mu) {
#ifdef GPR_LOW_LEVEL_COUNTERS
  GPR_ATM_INC_COUNTER(gpr_mu_locks);
#endif
  GPR_TIMER_SCOPE("gpr_mu_lock", 0);
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0);
#else
  GPR_ASSERT(pthread_mutex_lock(mu) == 0);
#endif
}

void gpr_mu_unlock(gpr_mu* mu) {
  GPR_TIMER_SCOPE("gpr_mu_unlock", 0);
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0);
#else
  GPR_ASSERT(pthread_mutex_unlock(mu) == 0);
#endif
}

int gpr_mu_trylock(gpr_mu* mu) {
  GPR_TIMER_SCOPE("gpr_mu_trylock", 0);
  int err = 0;
#ifdef GRPC_ASAN_ENABLED
  err = pthread_mutex_trylock(&mu->mutex);
#else
  err = pthread_mutex_trylock(mu);
#endif
  GPR_ASSERT(err == 0 || err == EBUSY);
  return err == 0;
}

/*----------------------------------------*/

void gpr_cv_init(gpr_cv* cv) {
  pthread_condattr_t attr;
  GPR_ASSERT(pthread_condattr_init(&attr) == 0);
#if GPR_LINUX
  GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0);
#endif  // GPR_LINUX

#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0);
  cv->leak_checker = static_cast<int*>(malloc(sizeof(*cv->leak_checker)));
  GPR_ASSERT(cv->leak_checker != nullptr);
#else
  GPR_ASSERT(pthread_cond_init(cv, &attr) == 0);
#endif
}

void gpr_cv_destroy(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0);
  free(cv->leak_checker);
#else
  GPR_ASSERT(pthread_cond_destroy(cv) == 0);
#endif
}

int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
  int err = 0;
  if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
      0) {
#ifdef GRPC_ASAN_ENABLED
    err = pthread_cond_wait(&cv->cond_var, &mu->mutex);
#else
    err = pthread_cond_wait(cv, mu);
#endif
  } else {
    struct timespec abs_deadline_ts;
#if GPR_LINUX
    abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC);
#else
    abs_deadline = gpr_time_max(abs_deadline, gpr_now(abs_deadline.clock_type));
    abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
#endif  // GPR_LINUX
    abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
    abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
#ifdef GRPC_ASAN_ENABLED
    err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts);
#else
    err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts);
#endif
  }
  GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN);
  return err == ETIMEDOUT;
}

void gpr_cv_signal(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0);
#else
  GPR_ASSERT(pthread_cond_signal(cv) == 0);
#endif
}

void gpr_cv_broadcast(gpr_cv* cv) {
#ifdef GRPC_ASAN_ENABLED
  GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0);
#else
  GPR_ASSERT(pthread_cond_broadcast(cv) == 0);
#endif
}

/*----------------------------------------*/

void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
  GPR_ASSERT(pthread_once(once, init_function) == 0);
}

#endif /* defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
          !defined(GPR_CUSTOM_SYNC) */
<|endoftext|>


<commit_before>/*
 * This file is part of crash-reporter
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * Contact: Ville Ilvonen <ville.p.ilvonen@nokia.com>
 * Author: Riku Halonen <riku.halonen@nokia.com>
 *
 * Copyright (C) 2013 Jolla Ltd.
 * Contact: Jakub Adam <jakub.adam@jollamobile.com>
 *
 * This program 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 program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

// User includes.

#include "creporterdaemon.h"
#include "creporterdaemon_p.h"
#include "creporterdaemonadaptor.h"
#include "creporterdaemonmonitor.h"
#include "creporternwsessionmgr.h"
#include "creportersavedstate.h"
#include "creportercoreregistry.h"
#include "creporterutils.h"
#include "creportersettingsobserver.h"
#include "creporternamespace.h"
#include "creporterprivacysettingsmodel.h"
#include "creporternotification.h"

#ifndef CREPORTER_UNIT_TEST
#include "creportersavedstate.h"
#endif

// ======== MEMBER FUNCTIONS ========

// ----------------------------------------------------------------------------
// CReporterDaemon::CReporterDaemon
// ----------------------------------------------------------------------------
CReporterDaemon::CReporterDaemon() :
    d_ptr(new CReporterDaemonPrivate())
{
    Q_D(CReporterDaemon);

    d->monitor = 0;
    d->timerId = 0;

    // Create registry instance preserving core locations.
    d->registry = new CReporterCoreRegistry();
    Q_CHECK_PTR(d->registry);

    // Adaptor class is deleted automatically, when the class, it is
    // attached to is deleted.
    new CReporterDaemonAdaptor(this);
}

// ----------------------------------------------------------------------------
// CReporterDaemon::~CReporterDaemon
// ----------------------------------------------------------------------------
CReporterDaemon::~CReporterDaemon()
{
    Q_D(CReporterDaemon);
    qDebug() << __PRETTY_FUNCTION__ << "Daemon destroyed.";

    if (d->monitor) {
        // Delete monitor instance and stop core monitoring.
        delete d->monitor;
        d->monitor = 0;
    }

	delete d->registry;
    d->registry = 0;

    CReporterPrivacySettingsModel::instance()->freeSingleton();
    CReporterSavedState::freeSingleton();

	delete d_ptr;
    d_ptr = 0;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::setDelayedStartup
// ----------------------------------------------------------------------------
void CReporterDaemon::setDelayedStartup(int timeout)
{
    Q_D(CReporterDaemon);

    qDebug() << __PRETTY_FUNCTION__ << "Delaying startup for" << timeout / 1000 << "seconds.";
    if (timeout > 0) {
        d->timerId = startTimer(timeout);
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::initiateDaemon
// ----------------------------------------------------------------------------
bool CReporterDaemon::initiateDaemon()
{
    qDebug() << __PRETTY_FUNCTION__ << "Starting daemon...";

    if (!CReporterPrivacySettingsModel::instance()->isValid())
    {
        qWarning() << __PRETTY_FUNCTION__ << "Invalid settings";
        // Exit, if settings are missing.
        return false;
    }

    QString filename = CReporterPrivacySettingsModel::instance()->settingsFile();

    if (!startService())
    {
		return false;
	}

    if (CReporterPrivacySettingsModel::instance()->notificationsEnabled()
        || CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
    {
        // Read from settings file, if monitor should be started.
        startCoreMonitoring();
    }

    // Create observer to monitor changes in settings.
    CReporterSettingsObserver *settingsObserver =
            new CReporterSettingsObserver(filename, this);

    settingsObserver->addWatcher(Settings::ValueNotifications);
    settingsObserver->addWatcher(Settings::ValueAutomaticSending);
    settingsObserver->addWatcher(Settings::ValueAutoDeleteDuplicates);

    connect(settingsObserver, SIGNAL(valueChanged(QString,QVariant)),
            this, SLOT(settingValueChanged(QString,QVariant)));

#ifndef CREPORTER_UNIT_TEST
    // Each time daemon is started, we count successful core uploads from zero.
    CReporterSavedState *state = CReporterSavedState::instance();
    state->setUploadSuccessCount(0);
    state->writeSettings();
#endif

    if (CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
    {
        QStringList files = collectAllCoreFiles();

        if (!files.isEmpty() &&
            CReporterNwSessionMgr::unpaidConnectionAvailable() &&
            !CReporterUtils::notifyAutoUploader(files))
        {
            qDebug() << __PRETTY_FUNCTION__ << "Failed to add files to the queue.";
        }
    }
    else if (CReporterPrivacySettingsModel::instance()->notificationsEnabled())
    {
        QStringList files = collectAllCoreFiles();

        if (!files.isEmpty()) {
            CReporterNotification *notification = new CReporterNotification(
                    CReporter::ApplicationNotificationEventType,
                    //% "This system has stored crash reports."
                    qtTrId("crash_reporter-notify-has_stored_cores"),
                    QString(), this);

            connect(notification, &CReporterNotification::timeouted,
                    notification, &CReporterNotification::deleteLater);
        }
    }

    return true;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::startCoreMonitoring
// ----------------------------------------------------------------------------
void CReporterDaemon::startCoreMonitoring(const bool fromDBus)
{
    Q_D(CReporterDaemon);

    qDebug() << __PRETTY_FUNCTION__ << "Core monitoring requested. Called from DBus ="
            << fromDBus;

    if (!d->monitor) {
		// Create monitor instance and start monitoring cores.
        d->monitor = new CReporterDaemonMonitor(d->registry);
        Q_CHECK_PTR(d->monitor);

        connect(d->monitor, SIGNAL(richCoreNotify(QString)), SLOT(newCoreDump(QString)));

        qDebug() << __PRETTY_FUNCTION__ << "Core monitoring started.";

        if (fromDBus) {
            CReporterPrivacySettingsModel::instance()->setNotificationsEnabled(true);
            CReporterPrivacySettingsModel::instance()->writeSettings();
        }
        d->monitor->setAutoDelete(CReporterPrivacySettingsModel::instance()->autoDeleteDuplicates());
        d->monitor->setAutoDeleteMaxSimilarCores(
                CReporterPrivacySettingsModel::instance()->autoDeleteMaxSimilarCores());
        d->monitor->setAutoUpload(CReporterPrivacySettingsModel::instance()->automaticSendingEnabled());
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::stopCoreMonitoring
// ----------------------------------------------------------------------------
void CReporterDaemon::stopCoreMonitoring(const bool fromDBus)
{
    Q_D(CReporterDaemon);

    if (d->monitor) {
		// Delete monitor instance and stop core monitoring.
		delete d->monitor;
        d->monitor = 0;

		qDebug() << __PRETTY_FUNCTION__ << "Core monitoring stopped.";

          if (fromDBus) {
              CReporterPrivacySettingsModel::instance()->setNotificationsEnabled(false);
              CReporterPrivacySettingsModel::instance()->writeSettings();
        }
	}
}

// ----------------------------------------------------------------------------
// CReporterDaemon::collectAllCoreFiles
// ----------------------------------------------------------------------------
QStringList CReporterDaemon::collectAllCoreFiles()
{
    Q_D(CReporterDaemon);

    return d->registry->collectAllCoreFiles();
}

// ======== LOCAL FUNCTIONS ========

// ----------------------------------------------------------------------------
// CReporterDaemon::settingValueChanged
// ----------------------------------------------------------------------------
void CReporterDaemon::settingValueChanged(const QString &key, const QVariant &value)
{
    qDebug() << __PRETTY_FUNCTION__ << "Setting:" << key << "has changed; value:" << value;
    if (key == Settings::ValueNotifications || key == Settings::ValueAutomaticSending)
    {
        if (value.toBool())
        {
            startCoreMonitoring();
        }
        else if (!CReporterPrivacySettingsModel::instance()->notificationsEnabled()
               && !CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
        {
            if (key == Settings::ValueAutomaticSending)
            {
                if (d_ptr->monitor)
                {
                    d_ptr->monitor->setAutoUpload(value.toBool());
                }
            }
            stopCoreMonitoring();
        }
    }
    else if (key == Settings::ValueAutoDeleteDuplicates)
    {
        if (d_ptr->monitor)
        {
            d_ptr->monitor->setAutoDelete(value.toBool());
        }
    }

    if (key == Settings::ValueAutomaticSending)
    {
        if (d_ptr->monitor)
        {
            d_ptr->monitor->setAutoUpload(value.toBool());
        }
    }
}

// ----------------------------------------------------------------------------
//  CReporterDaemon::timerEvent
// ----------------------------------------------------------------------------
void CReporterDaemon::timerEvent(QTimerEvent *event)
{
    Q_D(CReporterDaemon);
    qDebug() << __PRETTY_FUNCTION__ << "Startup timer elapsed -> start now.";

    if (event->timerId() != d->timerId) return;

    // Kill timer and initiate daemon.
    killTimer(d->timerId);
    d->timerId = 0;

    if (!initiateDaemon()) {
        // If D-Bus registration fails, quit application.
        qApp->quit();
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::startService
// ----------------------------------------------------------------------------
bool CReporterDaemon::startService()
{
	qDebug() << __PRETTY_FUNCTION__ << "Starting D-Bus service...";

    if (!QDBusConnection::sessionBus().isConnected()) {
	  qWarning() << __PRETTY_FUNCTION__ << "D-Bus not running?";
	  return false;
	  }

    if (!QDBusConnection::sessionBus().registerService(CReporter::DaemonServiceName)) {
      qWarning() << __PRETTY_FUNCTION__
              << "Failed to register service, daemon already running?";
      return false;
	  }

    qDebug() << __PRETTY_FUNCTION__ << "Service:"
            << CReporter::DaemonServiceName << "registered.";

    QDBusConnection::sessionBus().registerObject(CReporter::DaemonObjectPath, this);

    qDebug() << __PRETTY_FUNCTION__ << "Object:"
            << CReporter::DaemonObjectPath << "registered.";

    // Good to go.
	qDebug() << __PRETTY_FUNCTION__ << "D-Bus service started.";
	return true;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::stopService
// ----------------------------------------------------------------------------
void CReporterDaemon::stopService()
{
	qDebug() << __PRETTY_FUNCTION__ << "Stopping D-Bus service...";

    QDBusConnection::sessionBus().unregisterObject(CReporter::DaemonObjectPath);
    QDBusConnection::sessionBus().unregisterService(CReporter::DaemonServiceName);
}

// End of file
<commit_msg>[daemon] removed superfluous QObject::connect()<commit_after>/*
 * This file is part of crash-reporter
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * Contact: Ville Ilvonen <ville.p.ilvonen@nokia.com>
 * Author: Riku Halonen <riku.halonen@nokia.com>
 *
 * Copyright (C) 2013 Jolla Ltd.
 * Contact: Jakub Adam <jakub.adam@jollamobile.com>
 *
 * This program 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 program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

// User includes.

#include "creporterdaemon.h"
#include "creporterdaemon_p.h"
#include "creporterdaemonadaptor.h"
#include "creporterdaemonmonitor.h"
#include "creporternwsessionmgr.h"
#include "creportersavedstate.h"
#include "creportercoreregistry.h"
#include "creporterutils.h"
#include "creportersettingsobserver.h"
#include "creporternamespace.h"
#include "creporterprivacysettingsmodel.h"
#include "creporternotification.h"

#ifndef CREPORTER_UNIT_TEST
#include "creportersavedstate.h"
#endif

// ======== MEMBER FUNCTIONS ========

// ----------------------------------------------------------------------------
// CReporterDaemon::CReporterDaemon
// ----------------------------------------------------------------------------
CReporterDaemon::CReporterDaemon() :
    d_ptr(new CReporterDaemonPrivate())
{
    Q_D(CReporterDaemon);

    d->monitor = 0;
    d->timerId = 0;

    // Create registry instance preserving core locations.
    d->registry = new CReporterCoreRegistry();
    Q_CHECK_PTR(d->registry);

    // Adaptor class is deleted automatically, when the class, it is
    // attached to is deleted.
    new CReporterDaemonAdaptor(this);
}

// ----------------------------------------------------------------------------
// CReporterDaemon::~CReporterDaemon
// ----------------------------------------------------------------------------
CReporterDaemon::~CReporterDaemon()
{
    Q_D(CReporterDaemon);
    qDebug() << __PRETTY_FUNCTION__ << "Daemon destroyed.";

    if (d->monitor) {
        // Delete monitor instance and stop core monitoring.
        delete d->monitor;
        d->monitor = 0;
    }

	delete d->registry;
    d->registry = 0;

    CReporterPrivacySettingsModel::instance()->freeSingleton();
    CReporterSavedState::freeSingleton();

	delete d_ptr;
    d_ptr = 0;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::setDelayedStartup
// ----------------------------------------------------------------------------
void CReporterDaemon::setDelayedStartup(int timeout)
{
    Q_D(CReporterDaemon);

    qDebug() << __PRETTY_FUNCTION__ << "Delaying startup for" << timeout / 1000 << "seconds.";
    if (timeout > 0) {
        d->timerId = startTimer(timeout);
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::initiateDaemon
// ----------------------------------------------------------------------------
bool CReporterDaemon::initiateDaemon()
{
    qDebug() << __PRETTY_FUNCTION__ << "Starting daemon...";

    if (!CReporterPrivacySettingsModel::instance()->isValid())
    {
        qWarning() << __PRETTY_FUNCTION__ << "Invalid settings";
        // Exit, if settings are missing.
        return false;
    }

    QString filename = CReporterPrivacySettingsModel::instance()->settingsFile();

    if (!startService())
    {
		return false;
	}

    if (CReporterPrivacySettingsModel::instance()->notificationsEnabled()
        || CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
    {
        // Read from settings file, if monitor should be started.
        startCoreMonitoring();
    }

    // Create observer to monitor changes in settings.
    CReporterSettingsObserver *settingsObserver =
            new CReporterSettingsObserver(filename, this);

    settingsObserver->addWatcher(Settings::ValueNotifications);
    settingsObserver->addWatcher(Settings::ValueAutomaticSending);
    settingsObserver->addWatcher(Settings::ValueAutoDeleteDuplicates);

    connect(settingsObserver, SIGNAL(valueChanged(QString,QVariant)),
            this, SLOT(settingValueChanged(QString,QVariant)));

#ifndef CREPORTER_UNIT_TEST
    // Each time daemon is started, we count successful core uploads from zero.
    CReporterSavedState *state = CReporterSavedState::instance();
    state->setUploadSuccessCount(0);
    state->writeSettings();
#endif

    if (CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
    {
        QStringList files = collectAllCoreFiles();

        if (!files.isEmpty() &&
            CReporterNwSessionMgr::unpaidConnectionAvailable() &&
            !CReporterUtils::notifyAutoUploader(files))
        {
            qDebug() << __PRETTY_FUNCTION__ << "Failed to add files to the queue.";
        }
    }
    else if (CReporterPrivacySettingsModel::instance()->notificationsEnabled())
    {
        QStringList files = collectAllCoreFiles();

        if (!files.isEmpty()) {
            CReporterNotification *notification = new CReporterNotification(
                    CReporter::ApplicationNotificationEventType,
                    //% "This system has stored crash reports."
                    qtTrId("crash_reporter-notify-has_stored_cores"),
                    QString(), this);

            connect(notification, &CReporterNotification::timeouted,
                    notification, &CReporterNotification::deleteLater);
        }
    }

    return true;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::startCoreMonitoring
// ----------------------------------------------------------------------------
void CReporterDaemon::startCoreMonitoring(const bool fromDBus)
{
    Q_D(CReporterDaemon);

    qDebug() << __PRETTY_FUNCTION__ << "Core monitoring requested. Called from DBus ="
            << fromDBus;

    if (!d->monitor) {
		// Create monitor instance and start monitoring cores.
        d->monitor = new CReporterDaemonMonitor(d->registry);
        Q_CHECK_PTR(d->monitor);

        qDebug() << __PRETTY_FUNCTION__ << "Core monitoring started.";

        if (fromDBus) {
            CReporterPrivacySettingsModel::instance()->setNotificationsEnabled(true);
            CReporterPrivacySettingsModel::instance()->writeSettings();
        }
        d->monitor->setAutoDelete(CReporterPrivacySettingsModel::instance()->autoDeleteDuplicates());
        d->monitor->setAutoDeleteMaxSimilarCores(
                CReporterPrivacySettingsModel::instance()->autoDeleteMaxSimilarCores());
        d->monitor->setAutoUpload(CReporterPrivacySettingsModel::instance()->automaticSendingEnabled());
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::stopCoreMonitoring
// ----------------------------------------------------------------------------
void CReporterDaemon::stopCoreMonitoring(const bool fromDBus)
{
    Q_D(CReporterDaemon);

    if (d->monitor) {
		// Delete monitor instance and stop core monitoring.
		delete d->monitor;
        d->monitor = 0;

		qDebug() << __PRETTY_FUNCTION__ << "Core monitoring stopped.";

          if (fromDBus) {
              CReporterPrivacySettingsModel::instance()->setNotificationsEnabled(false);
              CReporterPrivacySettingsModel::instance()->writeSettings();
        }
	}
}

// ----------------------------------------------------------------------------
// CReporterDaemon::collectAllCoreFiles
// ----------------------------------------------------------------------------
QStringList CReporterDaemon::collectAllCoreFiles()
{
    Q_D(CReporterDaemon);

    return d->registry->collectAllCoreFiles();
}

// ======== LOCAL FUNCTIONS ========

// ----------------------------------------------------------------------------
// CReporterDaemon::settingValueChanged
// ----------------------------------------------------------------------------
void CReporterDaemon::settingValueChanged(const QString &key, const QVariant &value)
{
    qDebug() << __PRETTY_FUNCTION__ << "Setting:" << key << "has changed; value:" << value;
    if (key == Settings::ValueNotifications || key == Settings::ValueAutomaticSending)
    {
        if (value.toBool())
        {
            startCoreMonitoring();
        }
        else if (!CReporterPrivacySettingsModel::instance()->notificationsEnabled()
               && !CReporterPrivacySettingsModel::instance()->automaticSendingEnabled())
        {
            if (key == Settings::ValueAutomaticSending)
            {
                if (d_ptr->monitor)
                {
                    d_ptr->monitor->setAutoUpload(value.toBool());
                }
            }
            stopCoreMonitoring();
        }
    }
    else if (key == Settings::ValueAutoDeleteDuplicates)
    {
        if (d_ptr->monitor)
        {
            d_ptr->monitor->setAutoDelete(value.toBool());
        }
    }

    if (key == Settings::ValueAutomaticSending)
    {
        if (d_ptr->monitor)
        {
            d_ptr->monitor->setAutoUpload(value.toBool());
        }
    }
}

// ----------------------------------------------------------------------------
//  CReporterDaemon::timerEvent
// ----------------------------------------------------------------------------
void CReporterDaemon::timerEvent(QTimerEvent *event)
{
    Q_D(CReporterDaemon);
    qDebug() << __PRETTY_FUNCTION__ << "Startup timer elapsed -> start now.";

    if (event->timerId() != d->timerId) return;

    // Kill timer and initiate daemon.
    killTimer(d->timerId);
    d->timerId = 0;

    if (!initiateDaemon()) {
        // If D-Bus registration fails, quit application.
        qApp->quit();
    }
}

// ----------------------------------------------------------------------------
// CReporterDaemon::startService
// ----------------------------------------------------------------------------
bool CReporterDaemon::startService()
{
	qDebug() << __PRETTY_FUNCTION__ << "Starting D-Bus service...";

    if (!QDBusConnection::sessionBus().isConnected()) {
	  qWarning() << __PRETTY_FUNCTION__ << "D-Bus not running?";
	  return false;
	  }

    if (!QDBusConnection::sessionBus().registerService(CReporter::DaemonServiceName)) {
      qWarning() << __PRETTY_FUNCTION__
              << "Failed to register service, daemon already running?";
      return false;
	  }

    qDebug() << __PRETTY_FUNCTION__ << "Service:"
            << CReporter::DaemonServiceName << "registered.";

    QDBusConnection::sessionBus().registerObject(CReporter::DaemonObjectPath, this);

    qDebug() << __PRETTY_FUNCTION__ << "Object:"
            << CReporter::DaemonObjectPath << "registered.";

    // Good to go.
	qDebug() << __PRETTY_FUNCTION__ << "D-Bus service started.";
	return true;
}

// ----------------------------------------------------------------------------
// CReporterDaemon::stopService
// ----------------------------------------------------------------------------
void CReporterDaemon::stopService()
{
	qDebug() << __PRETTY_FUNCTION__ << "Stopping D-Bus service...";

    QDBusConnection::sessionBus().unregisterObject(CReporter::DaemonObjectPath);
    QDBusConnection::sessionBus().unregisterService(CReporter::DaemonServiceName);
}

// End of file
<|endoftext|>


<commit_before>

#include <signal.h>

#include "backend/common/message_queue.h"
#include "backend/common/logger.h"

#define NOTIFY_SIG SIGUSR1

namespace peloton {

void notify_message(mqd_t *mqdp);

std::string get_mq_name(oid_t id) {
  return std::string("/backend_" + std::to_string(id));
}

mqd_t create_mq(const std::string queue_name) {

  mqd_t mqd = mq_open(queue_name.c_str(),
                      O_CREAT | O_RDONLY | O_NONBLOCK,
                      S_IRUSR | S_IWUSR,
                      NULL);
  if (mqd == (mqd_t) -1) {
    LOG_ERROR("mq_open during create : %s pid : %d \n",
              queue_name.c_str(), getpid());
    return mqd;
  }

  LOG_TRACE("CREATED QUEUE :: %s getpid : %d \n",
         queue_name.c_str(), getpid());

  return mqd;
}

mqd_t open_mq(const std::string queue_name) {
  int flags;
  flags = O_WRONLY | O_NONBLOCK;

  mqd_t mqd = mq_open(queue_name.c_str(), flags);
  if (mqd == (mqd_t) -1) {
    perror("mq_open during open");
  }

  return mqd;
}

void send_message(mqd_t mqd, const std::string message) {
  int prio = 0;
  LOG_TRACE("TRYING TO SEND MESSAGE :: %s \n", message.c_str());

  if (mq_send(mqd, message.c_str(), message.size(), prio) == -1) {
    perror("mq_send");
  }

  LOG_TRACE("SENT MESSAGE \n");
}

static void
handler(int sig)
{
    /* Just interrupt sigsuspend() */
}

void receive_message(mqd_t *mqdp) {
  ssize_t numRead;
  void *buffer;
  struct mq_attr attr;

  LOG_TRACE("HANDLER START :: pid : %d \n", getpid());

  // Determine mq_msgsize for message queue, and allocate space
  if (mq_getattr(*mqdp, &attr) == -1)
    perror("mq_getattr");

  buffer = malloc(attr.mq_msgsize);
  if (buffer == NULL)
    perror("malloc");

  while ((numRead = mq_receive(*mqdp, (char *) buffer, attr.mq_msgsize, NULL)) >= 0)
    LOG_TRACE("Read %ld bytes\n", (long) numRead);

  if (errno != EAGAIN)                        /* Unexpected error */
    perror("mq_receive");

  free(buffer);
  LOG_TRACE("HANDLER DONE \n");
}

void notify_message(mqd_t *mqdp)
{
  struct sigevent sev;
  sigset_t blockMask;
  struct sigaction sa;

  LOG_TRACE("SETUP NOTIFY \n");

  /* Block the notification signal and establish a handler for it */

  sigemptyset(&blockMask);
  sigaddset(&blockMask, NOTIFY_SIG);
  if (sigprocmask(SIG_BLOCK, &blockMask, NULL) == -1)
    perror("sigprocmask");

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  sa.sa_handler = handler;
  if (sigaction(NOTIFY_SIG, &sa, NULL) == -1)
    perror("sigaction");

  /* Register for message notification via a signal */

  sev.sigev_notify = SIGEV_SIGNAL;
  sev.sigev_signo = NOTIFY_SIG;

  if (mq_notify(*mqdp, &sev) == -1)
    perror("mq_notify");

  LOG_TRACE("FINISHED SETUP NOTIFY \n");

}

void wait_for_message(mqd_t *mqdp) {
  sigset_t emptyMask;

  notify_message(mqdp);
  LOG_TRACE("GOING TO SUSPEND :: pid : %d \n", getpid());

  sigemptyset(&emptyMask);
  sigsuspend(&emptyMask); /* Wait for notification signal */

  LOG_TRACE("WOKE UP :: pid : %d \n", getpid());

  receive_message(mqdp);

  LOG_TRACE("FINISH PAUSE \n");
}

}  // End peloton namespace
<commit_msg>Clean up some stuff.<commit_after>

#include <signal.h>

#include "backend/common/message_queue.h"
#include "backend/common/logger.h"

#define NOTIFY_SIG SIGUSR1

namespace peloton {

void notify_message(mqd_t *mqdp);

std::string get_mq_name(oid_t id) {
  return std::string("/backend_" + std::to_string(id));
}

mqd_t create_mq(const std::string queue_name) {

  mqd_t mqd = mq_open(queue_name.c_str(),
                      O_CREAT | O_RDONLY | O_NONBLOCK,
                      S_IRUSR | S_IWUSR,
                      NULL);
  if (mqd == (mqd_t) -1) {
    LOG_ERROR("mq_open during create : %s pid : %d \n",
              queue_name.c_str(), getpid());
    return mqd;
  }
  LOG_TRACE("CREATED QUEUE :: %s getpid : %d \n",
         queue_name.c_str(), getpid());

  return mqd;
}

mqd_t open_mq(const std::string queue_name) {
  int flags;
  flags = O_WRONLY | O_NONBLOCK;

  mqd_t mqd = mq_open(queue_name.c_str(), flags);
  if (mqd == (mqd_t) -1) {
    perror("mq_open during open");
  }

  return mqd;
}

void send_message(mqd_t mqd, const std::string message) {
  int prio = 0;
  LOG_TRACE("TRYING TO SEND MESSAGE :: %s \n", message.c_str());

  if (mq_send(mqd, message.c_str(), message.size(), prio) == -1) {
    perror("mq_send");
  }

  LOG_TRACE("SENT MESSAGE \n");
}

static void
handler(int sig)
{
  // Just interrupt sigsuspend()
}

void receive_message(mqd_t *mqdp) {
  ssize_t chars_read;
  void *buffer;
  struct mq_attr attr;
  LOG_TRACE("HANDLER :: pid : %d \n", getpid());

  // Determine mq_msgsize for message queue, and allocate space
  if (mq_getattr(*mqdp, &attr) == -1)
    perror("mq_getattr");

  buffer = malloc(attr.mq_msgsize);
  if (buffer == NULL)
    perror("malloc");

  while ((chars_read = mq_receive(*mqdp, (char *) buffer, attr.mq_msgsize, NULL)) >= 0)
    LOG_TRACE("Read %ld bytes\n", (long) chars_read);

  if (errno != EAGAIN)  // Unexpected error
    perror("mq_receive");

  free(buffer);
}

void notify_message(mqd_t *mqdp)
{
  struct sigevent sev;
  sigset_t blockMask;
  struct sigaction sa;

  LOG_TRACE("SETUP NOTIFY \n");

  // Block the notification signal and establish a handler for it
  sigemptyset(&blockMask);
  sigaddset(&blockMask, NOTIFY_SIG);
  if (sigprocmask(SIG_BLOCK, &blockMask, NULL) == -1)
    perror("sigprocmask");

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  sa.sa_handler = handler;
  if (sigaction(NOTIFY_SIG, &sa, NULL) == -1)
    perror("sigaction");

  // Register for message notification via a signal
  sev.sigev_notify = SIGEV_SIGNAL;
  sev.sigev_signo = NOTIFY_SIG;

  if (mq_notify(*mqdp, &sev) == -1)
    perror("mq_notify");

}

void wait_for_message(mqd_t *mqdp) {
  sigset_t emptyMask;

  notify_message(mqdp);
  LOG_TRACE("SUSPENDING :: pid : %d \n", getpid());

  sigemptyset(&emptyMask);
  sigsuspend(&emptyMask); // Wait for notification signal

  LOG_TRACE("WOKE UP :: pid : %d \n", getpid());

  receive_message(mqdp);
}

}  // End peloton namespace
<|endoftext|>


<commit_before>#include "cdriver.h"

struct Apex {
	double axis_min, axis_max;	// Limits for the movement of this axis.
	double rodlength, radius;	// Length of the tie rod and the horizontal distance between the vertical position and the zero position.
	double x, y, z;		// Position of tower on the base plane, and the carriage height at zero position.
};

struct Delta_private {
	Apex apex[3];
	double angle;			// Adjust the front of the printer.
};

#define PRIVATE(s) (*reinterpret_cast <Delta_private *>(s->type_data))
#define APEX(s, a) (PRIVATE(s).apex[a])

static bool check_delta(Space *s, uint8_t a, double *target) {	// {{{
	double dx = target[0] - APEX(s, a).x;
	double dy = target[1] - APEX(s, a).y;
	double r2 = dx * dx + dy * dy;
	double amax = APEX(s, a).axis_max < APEX(s, a).rodlength ? APEX(s, a).axis_max : APEX(s, a).rodlength;
	if (r2 > amax * amax) {
		debug ("not ok 1: %f %f %f %f %f %f %f", target[0], target[1], dx, dy, r2, APEX(s, a).rodlength, APEX(s, a).axis_max);
		// target is too far away from axis.  Pull it towards axis so that it is on the edge.
		// target = axis + (target - axis) * (l - epsilon) / r.
		double factor(amax / sqrt(r2));
		target[0] = APEX(s, a).x + (target[0] - APEX(s, a).x) * factor;
		target[1] = APEX(s, a).y + (target[1] - APEX(s, a).y) * factor;
		return false;
	}
	// Inner product shows if projection is inside or outside the printable region.
	double projection = -(dx / APEX(s, a).radius * APEX(s, a).x + dy / APEX(s, a).radius * APEX(s, a).y);
	double amin = APEX(s, a).axis_min < -APEX(s, a).rodlength ? -APEX(s, a).rodlength : APEX(s, a).axis_min;
	if (projection < amin) {
		debug ("not ok 2: %f %f %f %f %f", projection, dx, dy, APEX(s, a).x, APEX(s, a).y);
		// target is on the wrong side of axis.  Pull it towards plane so it is on the edge.
		target[0] -= ((amin - projection) / APEX(s, a).radius - .001) * APEX(s, a).x;
		target[1] -= ((amin - projection) / APEX(s, a).radius - .001) * APEX(s, a).y;
		// Assume this was a small correction; that way, things will work even if numerical errors cause this to be called for the real move.
		return false;
	}
	//debug("ok %d %d %f", s->id, a, projection);
	return true;
}	// }}}

static inline double delta_to_axis(Space *s, uint8_t a, bool *ok) {
	double dx = s->axis[0]->settings.target - APEX(s, a).x;
	double dy = s->axis[1]->settings.target - APEX(s, a).y;
	double dz = s->axis[2]->settings.target - APEX(s, a).z;
	double r2 = dx * dx + dy * dy;
	double l2 = APEX(s, a).rodlength * APEX(s, a).rodlength;
	double dest = sqrt(l2 - r2) + dz;
	//debug("dta dx %f dy %f dz %f z %f, r %f target %f", dx, dy, dz, APEX(s, a).z, r, target);
	return dest;
}

static void xyz2motors(Space *s, double *motors, bool *ok) {
	if (isnan(s->axis[0]->settings.target) || isnan(s->axis[1]->settings.target) || isnan(s->axis[2]->settings.target)) {
		// Fill up missing targets.
		for (uint8_t aa = 0; aa < 3; ++aa) {
			if (isnan(s->axis[aa]->settings.target))
				s->axis[aa]->settings.target = s->axis[aa]->settings.current;
		}
	}
	for (uint8_t a = 0; a < 3; ++a) {
		if (motors)
			motors[a] = delta_to_axis(s, a, ok);
		else
			s->motor[a]->settings.endpos = delta_to_axis(s, a, ok);
	}
}

static void reset_pos (Space *s) {
	// All axes' current_pos must be valid and equal, in other words, x=y=0.
	double p[3];
	for (uint8_t i = 0; i < 3; ++i)
		p[i] = s->motor[i]->settings.current_pos / s->motor[i]->steps_per_unit;
	if (p[0] != p[1] || p[0] != p[2]) {
		//debug("resetpos fails");
		s->axis[0]->settings.source = NAN;
		s->axis[1]->settings.source = NAN;
		s->axis[2]->settings.source = NAN;
	}
	else {
		//debug("resetpos %f", p[0]);
		s->axis[0]->settings.source = 0;
		s->axis[1]->settings.source = 0;
		s->axis[2]->settings.source = p[0];
	}
}

static void check_position(Space *s, double *data) {
	if (isnan(data[0]) || isnan(data[1])) {
		// Cannot check; assume it's ok.
		return;
	}
	for (uint8_t counter = 0; counter < 2; ++counter) {
		bool ok = true;
		for (uint8_t a = 0; a < s->num_axes; ++a)
			ok &= check_delta(s, a, data);
		if (ok)
			break;
	}
}

static void load(Space *s, uint8_t old_type, int32_t &addr) {
	if (!s->setup_nums(3, 3)) {
		debug("Failed to set up delta axes");
		s->cancel_update();
		return;
	}
	for (uint8_t a = 0; a < 3; ++a) {
		APEX(s, a).axis_min = read_float(addr);
		APEX(s, a).axis_max = read_float(addr);
		APEX(s, a).rodlength = read_float(addr);
		APEX(s, a).radius = read_float(addr);
	}
	PRIVATE(s).angle = read_float(addr);
	if (isinf(PRIVATE(s).angle) || isnan(PRIVATE(s).angle))
		PRIVATE(s).angle = 0;
#define sin210 -.5
#define cos210 -0.8660254037844386	// .5*sqrt(3)
#define sin330 -.5
#define cos330 0.8660254037844386	// .5*sqrt(3)
#define sin90 1
	// Coordinates of axes (at angles 210, 330, 90; each with its own radius).
	double x[3], y[3];
	x[0] = APEX(s, 0).radius * cos210;
	y[0] = APEX(s, 0).radius * sin210;
	x[1] = APEX(s, 1).radius * cos330;
	y[1] = APEX(s, 1).radius * sin330;
	x[2] = 0;
	y[2] = APEX(s, 2).radius * sin90;
	for (uint8_t a = 0; a < 3; ++a) {
		APEX(s, a).x = x[a] * cos(PRIVATE(s).angle) - y[a] * sin(PRIVATE(s).angle);
		APEX(s, a).y = y[a] * cos(PRIVATE(s).angle) + x[a] * sin(PRIVATE(s).angle);
		APEX(s, a).z = sqrt(APEX(s, a).rodlength * APEX(s, a).rodlength - APEX(s, a).radius * APEX(s, a).radius);
	}
}

static void save(Space *s, int32_t &addr) {
	for (uint8_t a = 0; a < 3; ++a) {
		write_float(addr, APEX(s, a).axis_min);
		write_float(addr, APEX(s, a).axis_max);
		write_float(addr, APEX(s, a).rodlength);
		write_float(addr, APEX(s, a).radius);
	}
	write_float(addr, PRIVATE(s).angle);
}

static bool init(Space *s) {
	s->type_data = new Delta_private;
	if (!s->type_data)
		return false;
	return true;
}

static void free(Space *s) {
	delete reinterpret_cast <Delta_private *>(s->type_data);
}

static void afree(Space *s, int a) {
}

static double change0(Space *s, int axis, double value) {
	return value;
}

static double unchange0(Space *s, int axis, double value) {
	return value;
}

static double probe_speed(Space *s) {
	double max_spu = 0;
	for (int i = 0; i < s->num_motors; ++i)
		if (max_spu < s->motor[i]->steps_per_unit)
			max_spu = s->motor[i]->steps_per_unit;
	return 1e6 / hwtime_step / max_spu;
}

void Delta_init(int num) {
	space_types[num].xyz2motors = xyz2motors;
	space_types[num].reset_pos = reset_pos;
	space_types[num].check_position = check_position;
	space_types[num].load = load;
	space_types[num].save = save;
	space_types[num].init = init;
	space_types[num].free = free;
	space_types[num].afree = afree;
	space_types[num].change0 = change0;
	space_types[num].unchange0 = unchange0;
	space_types[num].probe_speed = probe_speed;
}
<commit_msg>fix check_position for single axis moves<commit_after>#include "cdriver.h"

struct Apex {
	double axis_min, axis_max;	// Limits for the movement of this axis.
	double rodlength, radius;	// Length of the tie rod and the horizontal distance between the vertical position and the zero position.
	double x, y, z;		// Position of tower on the base plane, and the carriage height at zero position.
};

struct Delta_private {
	Apex apex[3];
	double angle;			// Adjust the front of the printer.
};

#define PRIVATE(s) (*reinterpret_cast <Delta_private *>(s->type_data))
#define APEX(s, a) (PRIVATE(s).apex[a])

static bool check_delta(Space *s, uint8_t a, double *target) {	// {{{
	double dx = target[0] - APEX(s, a).x;
	double dy = target[1] - APEX(s, a).y;
	double r2 = dx * dx + dy * dy;
	double amax = APEX(s, a).axis_max < APEX(s, a).rodlength ? APEX(s, a).axis_max : APEX(s, a).rodlength;
	if (r2 > amax * amax) {
		debug ("not ok 1: %f %f %f %f %f %f %f", target[0], target[1], dx, dy, r2, APEX(s, a).rodlength, APEX(s, a).axis_max);
		// target is too far away from axis.  Pull it towards axis so that it is on the edge.
		// target = axis + (target - axis) * (l - epsilon) / r.
		double factor(amax / sqrt(r2));
		target[0] = APEX(s, a).x + (target[0] - APEX(s, a).x) * factor;
		target[1] = APEX(s, a).y + (target[1] - APEX(s, a).y) * factor;
		return false;
	}
	// Inner product shows if projection is inside or outside the printable region.
	double projection = -(dx / APEX(s, a).radius * APEX(s, a).x + dy / APEX(s, a).radius * APEX(s, a).y);
	double amin = APEX(s, a).axis_min < -APEX(s, a).rodlength ? -APEX(s, a).rodlength : APEX(s, a).axis_min;
	if (projection < amin) {
		debug ("not ok 2: %f %f %f %f %f", projection, dx, dy, APEX(s, a).x, APEX(s, a).y);
		// target is on the wrong side of axis.  Pull it towards plane so it is on the edge.
		target[0] -= ((amin - projection) / APEX(s, a).radius - .001) * APEX(s, a).x;
		target[1] -= ((amin - projection) / APEX(s, a).radius - .001) * APEX(s, a).y;
		// Assume this was a small correction; that way, things will work even if numerical errors cause this to be called for the real move.
		return false;
	}
	//debug("ok %d %d %f", s->id, a, projection);
	return true;
}	// }}}

static inline double delta_to_axis(Space *s, uint8_t a, bool *ok) {
	double dx = s->axis[0]->settings.target - APEX(s, a).x;
	double dy = s->axis[1]->settings.target - APEX(s, a).y;
	double dz = s->axis[2]->settings.target - APEX(s, a).z;
	double r2 = dx * dx + dy * dy;
	double l2 = APEX(s, a).rodlength * APEX(s, a).rodlength;
	double dest = sqrt(l2 - r2) + dz;
	//debug("dta dx %f dy %f dz %f z %f, r %f target %f", dx, dy, dz, APEX(s, a).z, r, target);
	return dest;
}

static void xyz2motors(Space *s, double *motors, bool *ok) {
	if (isnan(s->axis[0]->settings.target) || isnan(s->axis[1]->settings.target) || isnan(s->axis[2]->settings.target)) {
		// Fill up missing targets.
		for (uint8_t aa = 0; aa < 3; ++aa) {
			if (isnan(s->axis[aa]->settings.target))
				s->axis[aa]->settings.target = s->axis[aa]->settings.current;
		}
	}
	for (uint8_t a = 0; a < 3; ++a) {
		if (motors)
			motors[a] = delta_to_axis(s, a, ok);
		else
			s->motor[a]->settings.endpos = delta_to_axis(s, a, ok);
	}
}

static void reset_pos (Space *s) {
	// All axes' current_pos must be valid and equal, in other words, x=y=0.
	double p[3];
	for (uint8_t i = 0; i < 3; ++i)
		p[i] = s->motor[i]->settings.current_pos / s->motor[i]->steps_per_unit;
	if (p[0] != p[1] || p[0] != p[2]) {
		//debug("resetpos fails");
		s->axis[0]->settings.source = NAN;
		s->axis[1]->settings.source = NAN;
		s->axis[2]->settings.source = NAN;
	}
	else {
		//debug("resetpos %f", p[0]);
		s->axis[0]->settings.source = 0;
		s->axis[1]->settings.source = 0;
		s->axis[2]->settings.source = p[0];
	}
}

static void check_position(Space *s, double *data) {
	if (isnan(data[0]) || isnan(data[1])) {
		if (!isnan(data[0]))
			data[1] = s->axis[1]->settings.source;
		else if (!isnan(data[1]))
			data[0] = s->axis[0]->settings.source;
		else {
			// Cannot check; assume it's ok.
			return;
		}
	}
	for (uint8_t counter = 0; counter < 2; ++counter) {
		bool ok = true;
		for (uint8_t a = 0; a < s->num_axes; ++a)
			ok &= check_delta(s, a, data);
		if (ok)
			break;
	}
}

static void load(Space *s, uint8_t old_type, int32_t &addr) {
	if (!s->setup_nums(3, 3)) {
		debug("Failed to set up delta axes");
		s->cancel_update();
		return;
	}
	for (uint8_t a = 0; a < 3; ++a) {
		APEX(s, a).axis_min = read_float(addr);
		APEX(s, a).axis_max = read_float(addr);
		APEX(s, a).rodlength = read_float(addr);
		APEX(s, a).radius = read_float(addr);
	}
	PRIVATE(s).angle = read_float(addr);
	if (isinf(PRIVATE(s).angle) || isnan(PRIVATE(s).angle))
		PRIVATE(s).angle = 0;
#define sin210 -.5
#define cos210 -0.8660254037844386	// .5*sqrt(3)
#define sin330 -.5
#define cos330 0.8660254037844386	// .5*sqrt(3)
#define sin90 1
	// Coordinates of axes (at angles 210, 330, 90; each with its own radius).
	double x[3], y[3];
	x[0] = APEX(s, 0).radius * cos210;
	y[0] = APEX(s, 0).radius * sin210;
	x[1] = APEX(s, 1).radius * cos330;
	y[1] = APEX(s, 1).radius * sin330;
	x[2] = 0;
	y[2] = APEX(s, 2).radius * sin90;
	for (uint8_t a = 0; a < 3; ++a) {
		APEX(s, a).x = x[a] * cos(PRIVATE(s).angle) - y[a] * sin(PRIVATE(s).angle);
		APEX(s, a).y = y[a] * cos(PRIVATE(s).angle) + x[a] * sin(PRIVATE(s).angle);
		APEX(s, a).z = sqrt(APEX(s, a).rodlength * APEX(s, a).rodlength - APEX(s, a).radius * APEX(s, a).radius);
	}
}

static void save(Space *s, int32_t &addr) {
	for (uint8_t a = 0; a < 3; ++a) {
		write_float(addr, APEX(s, a).axis_min);
		write_float(addr, APEX(s, a).axis_max);
		write_float(addr, APEX(s, a).rodlength);
		write_float(addr, APEX(s, a).radius);
	}
	write_float(addr, PRIVATE(s).angle);
}

static bool init(Space *s) {
	s->type_data = new Delta_private;
	if (!s->type_data)
		return false;
	return true;
}

static void free(Space *s) {
	delete reinterpret_cast <Delta_private *>(s->type_data);
}

static void afree(Space *s, int a) {
}

static double change0(Space *s, int axis, double value) {
	return value;
}

static double unchange0(Space *s, int axis, double value) {
	return value;
}

static double probe_speed(Space *s) {
	double max_spu = 0;
	for (int i = 0; i < s->num_motors; ++i)
		if (max_spu < s->motor[i]->steps_per_unit)
			max_spu = s->motor[i]->steps_per_unit;
	return 1e6 / hwtime_step / max_spu;
}

void Delta_init(int num) {
	space_types[num].xyz2motors = xyz2motors;
	space_types[num].reset_pos = reset_pos;
	space_types[num].check_position = check_position;
	space_types[num].load = load;
	space_types[num].save = save;
	space_types[num].init = init;
	space_types[num].free = free;
	space_types[num].afree = afree;
	space_types[num].change0 = change0;
	space_types[num].unchange0 = unchange0;
	space_types[num].probe_speed = probe_speed;
}
<|endoftext|>


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

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    sal_uInt32          nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    using ScConditionEntry::operator==;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                BOOL bCompileEnglish = FALSE, BOOL bCompileXML = FALSE );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
    virtual ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    sal_uInt32      GetKey() const          { return nKey; }
    void            SetKey(sal_uInt32 nNew) { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to get a cell range from a list validation formula.
        @descr  The formula may contain a cell reference, a defined name or a database range.
        @param rRange  (out-param) The resulting cell range.
        @param rBaseAddr  Base address for relative references.
        @return  true = Cell range found, rRange is valid. */
    bool            GetRangeFromFormula( ScRange& rRange, const ScAddress& rBaseAddr, ScTokenArray& rTokArr, int nRecCount = 0 ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW)

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( sal_uInt32 nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<commit_msg>INTEGRATION: CWS dr54 (1.12.58); FILE MERGED 2007/05/25 16:49:45 er 1.12.58.1: #i56566# input validation with dynamic ranges as formua results<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: validat.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-03 15:46:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#ifndef SC_CONDITIO_HXX
#include "conditio.hxx"
#endif
#ifndef _COM_SUN_STAR_SHEET_TABLEVALIDATIONVISIBILITY_HPP_
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#endif

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedStrCollection;

enum ScValidationMode
{
    SC_VALID_ANY,
    SC_VALID_WHOLE,
    SC_VALID_DECIMAL,
    SC_VALID_DATE,
    SC_VALID_TIME,
    SC_VALID_TEXTLEN,
    SC_VALID_LIST,
    SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
    SC_VALERR_STOP,
    SC_VALERR_WARNING,
    SC_VALERR_INFO,
    SC_VALERR_MACRO
};

//
//  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class ScValidationData : public ScConditionEntry
{
    sal_uInt32          nKey;               // Index in Attributen

    ScValidationMode    eDataMode;
    BOOL                bShowInput;
    BOOL                bShowError;
    ScValidErrorStyle   eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
    String              aInputTitle;
    String              aInputMessage;
    String              aErrorTitle;
    String              aErrorMessage;

    BOOL                bIsUsed;            // temporaer beim Speichern

    BOOL            DoMacro( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    BOOL            DoScript( const ScAddress& rPos, const String& rInput,
                                ScFormulaCell* pCell, Window* pParent ) const;

    using ScConditionEntry::operator==;

public:
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const String& rExpr1, const String& rExpr2,
                                ScDocument* pDocument, const ScAddress& rPos,
                                BOOL bCompileEnglish = FALSE, BOOL bCompileXML = FALSE );
            ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
                                const ScTokenArray* pArr1, const ScTokenArray* pArr2,
                                ScDocument* pDocument, const ScAddress& rPos );
            ScValidationData( const ScValidationData& r );
            ScValidationData( ScDocument* pDocument, const ScValidationData& r );
            ScValidationData( SvStream& rStream, ScMultipleReadHeader& rHdr,
                                ScDocument* pDocument );
    virtual ~ScValidationData();

    void            Store(SvStream& rStream, ScMultipleWriteHeader& rHdr) const;

    ScValidationData* Clone() const     // echte Kopie
                    { return new ScValidationData( GetDocument(), *this ); }
    ScValidationData* Clone(ScDocument* pNew) const
                    { return new ScValidationData( pNew, *this ); }

    void            ResetInput();
    void            ResetError();
    void            SetInput( const String& rTitle, const String& rMsg );
    void            SetError( const String& rTitle, const String& rMsg,
                                ScValidErrorStyle eStyle );

    BOOL            GetInput( String& rTitle, String& rMsg ) const
                        { rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
    BOOL            GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

    BOOL            HasErrMsg() const       { return bShowError; }

    ScValidationMode GetDataMode() const    { return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedStrCollection& rStrings, const ScAddress& rPos ) const;

                    //  mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
    BOOL            IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
                                    const ScAddress& rPos ) const;
    BOOL            IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

                    // TRUE -> Abbruch
    BOOL            DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
    void            DoCalcError( ScFormulaCell* pCell ) const;

    BOOL            IsEmpty() const;
    sal_uInt32      GetKey() const          { return nKey; }
    void            SetKey(sal_uInt32 nNew) { nKey = nNew; }    // nur wenn nicht eingefuegt!

    void            SetUsed(BOOL bSet)      { bIsUsed = bSet; }
    BOOL            IsUsed() const          { return bIsUsed; }

    BOOL            EqualEntries( const ScValidationData& r ) const;    // fuer Undo

    //  sortiert (per PTRARR) nach Index
    //  operator== nur fuer die Sortierung
    BOOL operator ==( const ScValidationData& r ) const { return nKey == r.nKey; }
    BOOL operator < ( const ScValidationData& r ) const { return nKey <  r.nKey; }

private:
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only if it is non-NULL,
        @param pStrings  (out-param) Optionally NULL, string list to fill with list validation entires.
        @param pCell     can be NULL if it is not necessary to which element in the list is selected.
        @param rPos      the base address for relative references.
        @param rTokArr   Formula token array.
        @param rMatch    (out-param) the index of the first item that matched, -1 if nothing matched.
        @return  true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */
    bool            GetSelectionFromFormula( TypedStrCollection* pStrings,
                                             ScBaseCell* pCell, const ScAddress& rPos,
                                             const ScTokenArray& rTokArr, int& rMatch ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//  Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW)

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
        ScValidationDataList() {}
        ScValidationDataList(const ScValidationDataList& rList);
        ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
        ~ScValidationDataList() {}

    void    InsertNew( ScValidationData* pNew )
                { if (!Insert(pNew)) delete pNew; }

    ScValidationData* GetData( sal_uInt32 nKey );

    void    Load( SvStream& rStream, ScDocument* pDocument );
    void    Store( SvStream& rStream ) const;
    void    ResetUsed();

    void    CompileXML();
    void    UpdateReference( UpdateRefMode eUpdateRefMode,
                                const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );

    BOOL    operator==( const ScValidationDataList& r ) const;      // fuer Ref-Undo
};

#endif

<|endoftext|>


<commit_before>#ifndef PHPCXX_ARRAY_TCC
#define PHPCXX_ARRAY_TCC

#ifndef PHPCXX_ARRAY_H
#error "Please do not include this file directly, use array.h instead"
#endif

namespace phpcxx {

template<typename T>
Array& Array::operator=(const vector<T>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, v.size() ZEND_FILE_LINE_CC);
    for (std::size_t i=0; i<v.size(); ++i) {
        zval x;
        construct_zval(x, v[i]);
        zend_hash_next_index_insert_new(Z_ARR_P(z), &x);
    }

    return *this;
}

template<typename K, typename V, enable_if_t<std::is_integral<K>::value>*>
Array& Array::operator=(const map<K, V>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, 8 ZEND_FILE_LINE_CC);
    for (auto const& it : v) {
        zval x;
        construct_zval(x, it.second);
        zend_hash_index_add(Z_ARR_P(z), static_cast<zend_ulong>(it.first), &x);
    }

    return *this;
}

template<typename K, typename V, enable_if_t<is_pchar<K>::value || is_string<K>::value>*>
Array& Array::operator=(const map<K, V>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, 8 ZEND_FILE_LINE_CC);
    for (auto const& it : v) {
        zval x;
        construct_zval(x, it.second);
        ZendString key(it.first);
        zend_hash_add(Z_ARR_P(z), key.get(), &x);
    }

    return *this;
}

}

#endif /* PHPCXX_ARRAY_TCC */
<commit_msg>Use map.size() in call to _array_init()<commit_after>#ifndef PHPCXX_ARRAY_TCC
#define PHPCXX_ARRAY_TCC

#ifndef PHPCXX_ARRAY_H
#error "Please do not include this file directly, use array.h instead"
#endif

namespace phpcxx {

template<typename T>
Array& Array::operator=(const vector<T>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, v.size() ZEND_FILE_LINE_CC);
    for (std::size_t i=0; i<v.size(); ++i) {
        zval x;
        construct_zval(x, v[i]);
        zend_hash_next_index_insert_new(Z_ARR_P(z), &x);
    }

    return *this;
}

template<typename K, typename V, enable_if_t<std::is_integral<K>::value>*>
Array& Array::operator=(const map<K, V>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, v.size() ZEND_FILE_LINE_CC);
    for (auto const& it : v) {
        zval x;
        construct_zval(x, it.second);
        zend_hash_index_add(Z_ARR_P(z), static_cast<zend_ulong>(it.first), &x);
    }

    return *this;
}

template<typename K, typename V, enable_if_t<is_pchar<K>::value || is_string<K>::value>*>
Array& Array::operator=(const map<K, V>& v)
{
    zval* z = &this->m_z;
    ZVAL_DEREF(z);

    zval_ptr_dtor(z);
    _array_init(z, v.size() ZEND_FILE_LINE_CC);
    for (auto const& it : v) {
        zval x;
        construct_zval(x, it.second);
        ZendString key(it.first);
        zend_hash_add(Z_ARR_P(z), key.get(), &x);
    }

    return *this;
}

}

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