<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/message_center/message_center_impl.h"

#include "base/observer_list.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/notification_types.h"

namespace {

base::TimeDelta GetTimeoutForPriority(int priority) {
  if (priority > message_center::DEFAULT_PRIORITY) {
    return base::TimeDelta::FromSeconds(
        message_center::kAutocloseHighPriorityDelaySeconds);
  }
  return base::TimeDelta::FromSeconds(
      message_center::kAutocloseDefaultDelaySeconds);
}

}  // namespace

namespace message_center {
namespace internal {

////////////////////////////////////////////////////////////////////////////////
// PopupTimer

PopupTimer::PopupTimer(const std::string& id,
                       base::TimeDelta timeout,
                       base::WeakPtr<PopupTimersController> controller)
    : id_(id),
      timeout_(timeout),
      timer_controller_(controller),
      timer_(new base::OneShotTimer<PopupTimersController>) {}

PopupTimer::~PopupTimer() {
  if (!timer_)
    return;

  if (timer_->IsRunning())
    timer_->Stop();
}

void PopupTimer::Start() {
  if (timer_->IsRunning())
    return;
  base::TimeDelta timeout_to_close =
      timeout_ <= passed_ ? base::TimeDelta() : timeout_ - passed_;
  start_time_ = base::Time::Now();
  timer_->Start(
      FROM_HERE,
      timeout_to_close,
      base::Bind(
          &PopupTimersController::TimerFinished, timer_controller_, id_));
}

void PopupTimer::Pause() {
  if (!timer_.get() || !timer_->IsRunning())
    return;

  timer_->Stop();
  passed_ += base::Time::Now() - start_time_;
}

void PopupTimer::Reset() {
  if (timer_)
    timer_->Stop();
  passed_ = base::TimeDelta();
}

////////////////////////////////////////////////////////////////////////////////
// PopupTimersController

PopupTimersController::PopupTimersController(MessageCenter* message_center)
    : message_center_(message_center), popup_deleter_(&popup_timers_) {
  message_center_->AddObserver(this);
}

PopupTimersController::~PopupTimersController() {
  message_center_->RemoveObserver(this);
}

void PopupTimersController::StartTimer(const std::string& id,
                                       const base::TimeDelta& timeout) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter != popup_timers_.end()) {
    DCHECK(iter->second);
    iter->second->Start();
    return;
  }

  PopupTimer* timer = new PopupTimer(id, timeout, AsWeakPtr());

  timer->Start();
  popup_timers_[id] = timer;
}

void PopupTimersController::StartAll() {
  std::map<std::string, PopupTimer*>::iterator iter;
  for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
    iter->second->Start();
  }
}

void PopupTimersController::ResetTimer(const std::string& id,
                                       const base::TimeDelta& timeout) {
  CancelTimer(id);
  StartTimer(id, timeout);
}

void PopupTimersController::PauseTimer(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;
  iter->second->Pause();
}

void PopupTimersController::PauseAll() {
  std::map<std::string, PopupTimer*>::iterator iter;
  for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
    iter->second->Pause();
  }
}

void PopupTimersController::CancelTimer(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;

  PopupTimer* timer = iter->second;
  delete timer;

  popup_timers_.erase(iter);
}

void PopupTimersController::CancelAll() {
  STLDeleteValues(&popup_timers_);
  popup_timers_.clear();
}

void PopupTimersController::TimerFinished(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;

  CancelTimer(id);
  message_center_->MarkSinglePopupAsShown(id, false);
}

void PopupTimersController::OnNotificationDisplayed(const std::string& id) {
  OnNotificationUpdated(id);
}

void PopupTimersController::OnNotificationUpdated(const std::string& id) {
  NotificationList::PopupNotifications popup_notifications =
      message_center_->GetPopupNotifications();

  if (!popup_notifications.size()) {
    CancelAll();
    return;
  }

  NotificationList::PopupNotifications::const_iterator iter =
      popup_notifications.begin();
  for (; iter != popup_notifications.end(); iter++) {
    if ((*iter)->id() == id)
      break;
  }

  if (iter == popup_notifications.end() || (*iter)->never_timeout()) {
    CancelTimer(id);
    return;
  }

  // Start the timer if not yet.
  if (popup_timers_.find(id) == popup_timers_.end())
    StartTimer(id, GetTimeoutForPriority((*iter)->priority()));
}

void PopupTimersController::OnNotificationRemoved(const std::string& id,
                                                  bool by_user) {
  CancelTimer(id);
}

}  // namespace internal

////////////////////////////////////////////////////////////////////////////////
// MessageCenterImpl

MessageCenterImpl::MessageCenterImpl()
    : MessageCenter(),
      popup_timers_controller_(new internal::PopupTimersController(this)),
      delegate_(NULL),
      settings_provider_(NULL) {
  notification_list_.reset(new NotificationList());
}

MessageCenterImpl::~MessageCenterImpl() {
  notification_list_.reset();
}

void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) {
  observer_list_.AddObserver(observer);
}

void MessageCenterImpl::RemoveObserver(MessageCenterObserver* observer) {
  observer_list_.RemoveObserver(observer);
}

void MessageCenterImpl::SetDelegate(Delegate* delegate) {
  delegate_ = delegate;
}

void MessageCenterImpl::SetMessageCenterVisible(bool visible) {
  std::set<std::string> updated_ids;
  notification_list_->SetMessageCenterVisible(visible, &updated_ids);
  for (std::set<std::string>::const_iterator iter = updated_ids.begin();
       iter != updated_ids.end();
       ++iter) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(*iter));
  }

  if (!visible) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationCenterClosed());
  }
}

bool MessageCenterImpl::IsMessageCenterVisible() {
  return notification_list_->is_message_center_visible();
}

size_t MessageCenterImpl::NotificationCount() const {
  return notification_list_->NotificationCount();
}

size_t MessageCenterImpl::UnreadNotificationCount() const {
  return notification_list_->unread_count();
}

bool MessageCenterImpl::HasPopupNotifications() const {
  return notification_list_->HasPopupNotifications();
}

bool MessageCenterImpl::HasNotification(const std::string& id) {
  return notification_list_->HasNotification(id);
}

bool MessageCenterImpl::IsQuietMode() const {
  return notification_list_->quiet_mode();
}

bool MessageCenterImpl::HasClickedListener(const std::string& id) {
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  return delegate && delegate->HasClickedListener();
}

const NotificationList::Notifications& MessageCenterImpl::GetNotifications() {
  return notification_list_->GetNotifications();
}

NotificationList::PopupNotifications
    MessageCenterImpl::GetPopupNotifications() {
  return notification_list_->GetPopupNotifications();
}

//------------------------------------------------------------------------------
// Client code interface.
void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) {
  DCHECK(notification.get());

  // Sometimes the notification can be added with the same id and the
  // |notification_list| will replace the notification instead of adding new.
  // This is essentially an update rather than addition.
  const std::string& id = notification->id();
  bool already_exists = notification_list_->HasNotification(id);
  notification_list_->AddNotification(notification.Pass());

  if (already_exists) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
  } else {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationAdded(id));
  }
}

void MessageCenterImpl::UpdateNotification(
    const std::string& old_id,
    scoped_ptr<Notification> new_notification) {
  std::string new_id = new_notification->id();
  notification_list_->UpdateNotificationMessage(old_id,
                                                new_notification.Pass());
  if (old_id == new_id) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(new_id));
  } else {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationRemoved(old_id, false));
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationAdded(new_id));
  }
}

void MessageCenterImpl::RemoveNotification(const std::string& id,
                                           bool by_user) {
  if (!HasNotification(id))
    return;

  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Close(by_user);

  // In many cases |id| is a reference to an existing notification instance
  // but the instance can be destructed in RemoveNotification(). Hence
  // copies the id explicitly here.
  std::string copied_id(id);
  notification_list_->RemoveNotification(copied_id);
  FOR_EACH_OBSERVER(MessageCenterObserver,
                    observer_list_,
                    OnNotificationRemoved(copied_id, by_user));
}

void MessageCenterImpl::RemoveAllNotifications(bool by_user) {
  const NotificationList::Notifications& notifications =
      notification_list_->GetNotifications();
  std::set<std::string> ids;
  for (NotificationList::Notifications::const_iterator iter =
           notifications.begin(); iter != notifications.end(); ++iter) {
    ids.insert((*iter)->id());
  }
  notification_list_->RemoveAllNotifications();

  for (std::set<std::string>::const_iterator iter = ids.begin();
       iter != ids.end(); ++iter) {
    FOR_EACH_OBSERVER(MessageCenterObserver,
                      observer_list_,
                      OnNotificationRemoved(*iter, by_user));
  }
}

void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
                                        const gfx::Image& image) {
  if (notification_list_->SetNotificationIcon(notification_id, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
                                         const gfx::Image& image) {
  if (notification_list_->SetNotificationImage(notification_id, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::SetNotificationButtonIcon(
    const std::string& notification_id, int button_index,
    const gfx::Image& image) {
  if (!HasNotification(notification_id))
    return;
  if (notification_list_->SetNotificationButtonIcon(notification_id,
                                                    button_index, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::DisableNotificationsByNotifier(
    const NotifierId& notifier_id) {
  if (settings_provider_) {
    // TODO(mukai): SetNotifierEnabled can just accept notifier_id?
    Notifier notifier(notifier_id, base::string16(), true);
    settings_provider_->SetNotifierEnabled(notifier, false);
  }

  NotificationList::Notifications notifications =
      notification_list_->GetNotificationsByNotifierId(notifier_id);
  for (NotificationList::Notifications::const_iterator iter =
           notifications.begin(); iter != notifications.end();) {
    std::string id = (*iter)->id();
    iter++;
    RemoveNotification(id, false);
  }
}

void MessageCenterImpl::ShowNotificationSettings(const std::string& id) {
  if (delegate_)
    delegate_->ShowSettings(id);
}

void MessageCenterImpl::ExpandNotification(const std::string& id) {
  if (!HasNotification(id))
    return;
  notification_list_->MarkNotificationAsExpanded(id);
  FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                    OnNotificationUpdated(id));
}

void MessageCenterImpl::ClickOnNotification(const std::string& id) {
  if (!HasNotification(id))
    return;
  if (HasPopupNotifications())
    MarkSinglePopupAsShown(id, true);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Click();
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationClicked(id));
}

void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
                                              int button_index) {
  if (!HasNotification(id))
    return;
  if (HasPopupNotifications())
    MarkSinglePopupAsShown(id, true);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->ButtonClick(button_index);
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationButtonClicked(
          id, button_index));
}

void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
                                               bool mark_notification_as_read) {
  if (!HasNotification(id))
    return;
  notification_list_->MarkSinglePopupAsShown(id, mark_notification_as_read);
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
}

void MessageCenterImpl::DisplayedNotification(const std::string& id) {
  if (!HasNotification(id))
    return;

  if (HasPopupNotifications())
    notification_list_->MarkSinglePopupAsDisplayed(id);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Display();
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationDisplayed(id));
}

void MessageCenterImpl::SetNotifierSettingsProvider(
    NotifierSettingsProvider* provider) {
  settings_provider_ = provider;
}

NotifierSettingsProvider* MessageCenterImpl::GetNotifierSettingsProvider() {
  return settings_provider_;
}

void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
  if (in_quiet_mode != notification_list_->quiet_mode()) {
    notification_list_->SetQuietMode(in_quiet_mode);
    FOR_EACH_OBSERVER(MessageCenterObserver,
                      observer_list_,
                      OnQuietModeChanged(in_quiet_mode));
  }
  quiet_mode_timer_.reset();
}

void MessageCenterImpl::EnterQuietModeWithExpire(
    const base::TimeDelta& expires_in) {
  if (quiet_mode_timer_.get()) {
    // Note that the capital Reset() is the method to restart the timer, not
    // scoped_ptr::reset().
    quiet_mode_timer_->Reset();
  } else {
    notification_list_->SetQuietMode(true);
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnQuietModeChanged(true));

    quiet_mode_timer_.reset(new base::OneShotTimer<MessageCenterImpl>);
    quiet_mode_timer_->Start(
        FROM_HERE,
        expires_in,
        base::Bind(
            &MessageCenterImpl::SetQuietMode, base::Unretained(this), false));
  }
}

void MessageCenterImpl::RestartPopupTimers() {
  if (popup_timers_controller_.get())
    popup_timers_controller_->StartAll();
}

void MessageCenterImpl::PausePopupTimers() {
  if (popup_timers_controller_.get())
    popup_timers_controller_->PauseAll();
}

void MessageCenterImpl::DisableTimersForTest() {
  popup_timers_controller_.reset();
}

}  // namespace message_center
<commit_msg>Fire notifications' close callback on clear-all.<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/message_center/message_center_impl.h"

#include "base/observer_list.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/notification_types.h"

namespace {

base::TimeDelta GetTimeoutForPriority(int priority) {
  if (priority > message_center::DEFAULT_PRIORITY) {
    return base::TimeDelta::FromSeconds(
        message_center::kAutocloseHighPriorityDelaySeconds);
  }
  return base::TimeDelta::FromSeconds(
      message_center::kAutocloseDefaultDelaySeconds);
}

}  // namespace

namespace message_center {
namespace internal {

////////////////////////////////////////////////////////////////////////////////
// PopupTimer

PopupTimer::PopupTimer(const std::string& id,
                       base::TimeDelta timeout,
                       base::WeakPtr<PopupTimersController> controller)
    : id_(id),
      timeout_(timeout),
      timer_controller_(controller),
      timer_(new base::OneShotTimer<PopupTimersController>) {}

PopupTimer::~PopupTimer() {
  if (!timer_)
    return;

  if (timer_->IsRunning())
    timer_->Stop();
}

void PopupTimer::Start() {
  if (timer_->IsRunning())
    return;
  base::TimeDelta timeout_to_close =
      timeout_ <= passed_ ? base::TimeDelta() : timeout_ - passed_;
  start_time_ = base::Time::Now();
  timer_->Start(
      FROM_HERE,
      timeout_to_close,
      base::Bind(
          &PopupTimersController::TimerFinished, timer_controller_, id_));
}

void PopupTimer::Pause() {
  if (!timer_.get() || !timer_->IsRunning())
    return;

  timer_->Stop();
  passed_ += base::Time::Now() - start_time_;
}

void PopupTimer::Reset() {
  if (timer_)
    timer_->Stop();
  passed_ = base::TimeDelta();
}

////////////////////////////////////////////////////////////////////////////////
// PopupTimersController

PopupTimersController::PopupTimersController(MessageCenter* message_center)
    : message_center_(message_center), popup_deleter_(&popup_timers_) {
  message_center_->AddObserver(this);
}

PopupTimersController::~PopupTimersController() {
  message_center_->RemoveObserver(this);
}

void PopupTimersController::StartTimer(const std::string& id,
                                       const base::TimeDelta& timeout) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter != popup_timers_.end()) {
    DCHECK(iter->second);
    iter->second->Start();
    return;
  }

  PopupTimer* timer = new PopupTimer(id, timeout, AsWeakPtr());

  timer->Start();
  popup_timers_[id] = timer;
}

void PopupTimersController::StartAll() {
  std::map<std::string, PopupTimer*>::iterator iter;
  for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
    iter->second->Start();
  }
}

void PopupTimersController::ResetTimer(const std::string& id,
                                       const base::TimeDelta& timeout) {
  CancelTimer(id);
  StartTimer(id, timeout);
}

void PopupTimersController::PauseTimer(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;
  iter->second->Pause();
}

void PopupTimersController::PauseAll() {
  std::map<std::string, PopupTimer*>::iterator iter;
  for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
    iter->second->Pause();
  }
}

void PopupTimersController::CancelTimer(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;

  PopupTimer* timer = iter->second;
  delete timer;

  popup_timers_.erase(iter);
}

void PopupTimersController::CancelAll() {
  STLDeleteValues(&popup_timers_);
  popup_timers_.clear();
}

void PopupTimersController::TimerFinished(const std::string& id) {
  PopupTimerCollection::iterator iter = popup_timers_.find(id);
  if (iter == popup_timers_.end())
    return;

  CancelTimer(id);
  message_center_->MarkSinglePopupAsShown(id, false);
}

void PopupTimersController::OnNotificationDisplayed(const std::string& id) {
  OnNotificationUpdated(id);
}

void PopupTimersController::OnNotificationUpdated(const std::string& id) {
  NotificationList::PopupNotifications popup_notifications =
      message_center_->GetPopupNotifications();

  if (!popup_notifications.size()) {
    CancelAll();
    return;
  }

  NotificationList::PopupNotifications::const_iterator iter =
      popup_notifications.begin();
  for (; iter != popup_notifications.end(); iter++) {
    if ((*iter)->id() == id)
      break;
  }

  if (iter == popup_notifications.end() || (*iter)->never_timeout()) {
    CancelTimer(id);
    return;
  }

  // Start the timer if not yet.
  if (popup_timers_.find(id) == popup_timers_.end())
    StartTimer(id, GetTimeoutForPriority((*iter)->priority()));
}

void PopupTimersController::OnNotificationRemoved(const std::string& id,
                                                  bool by_user) {
  CancelTimer(id);
}

}  // namespace internal

////////////////////////////////////////////////////////////////////////////////
// MessageCenterImpl

MessageCenterImpl::MessageCenterImpl()
    : MessageCenter(),
      popup_timers_controller_(new internal::PopupTimersController(this)),
      delegate_(NULL),
      settings_provider_(NULL) {
  notification_list_.reset(new NotificationList());
}

MessageCenterImpl::~MessageCenterImpl() {
  notification_list_.reset();
}

void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) {
  observer_list_.AddObserver(observer);
}

void MessageCenterImpl::RemoveObserver(MessageCenterObserver* observer) {
  observer_list_.RemoveObserver(observer);
}

void MessageCenterImpl::SetDelegate(Delegate* delegate) {
  delegate_ = delegate;
}

void MessageCenterImpl::SetMessageCenterVisible(bool visible) {
  std::set<std::string> updated_ids;
  notification_list_->SetMessageCenterVisible(visible, &updated_ids);
  for (std::set<std::string>::const_iterator iter = updated_ids.begin();
       iter != updated_ids.end();
       ++iter) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(*iter));
  }

  if (!visible) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationCenterClosed());
  }
}

bool MessageCenterImpl::IsMessageCenterVisible() {
  return notification_list_->is_message_center_visible();
}

size_t MessageCenterImpl::NotificationCount() const {
  return notification_list_->NotificationCount();
}

size_t MessageCenterImpl::UnreadNotificationCount() const {
  return notification_list_->unread_count();
}

bool MessageCenterImpl::HasPopupNotifications() const {
  return notification_list_->HasPopupNotifications();
}

bool MessageCenterImpl::HasNotification(const std::string& id) {
  return notification_list_->HasNotification(id);
}

bool MessageCenterImpl::IsQuietMode() const {
  return notification_list_->quiet_mode();
}

bool MessageCenterImpl::HasClickedListener(const std::string& id) {
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  return delegate && delegate->HasClickedListener();
}

const NotificationList::Notifications& MessageCenterImpl::GetNotifications() {
  return notification_list_->GetNotifications();
}

NotificationList::PopupNotifications
    MessageCenterImpl::GetPopupNotifications() {
  return notification_list_->GetPopupNotifications();
}

//------------------------------------------------------------------------------
// Client code interface.
void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) {
  DCHECK(notification.get());

  // Sometimes the notification can be added with the same id and the
  // |notification_list| will replace the notification instead of adding new.
  // This is essentially an update rather than addition.
  const std::string& id = notification->id();
  bool already_exists = notification_list_->HasNotification(id);
  notification_list_->AddNotification(notification.Pass());

  if (already_exists) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
  } else {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationAdded(id));
  }
}

void MessageCenterImpl::UpdateNotification(
    const std::string& old_id,
    scoped_ptr<Notification> new_notification) {
  std::string new_id = new_notification->id();
  notification_list_->UpdateNotificationMessage(old_id,
                                                new_notification.Pass());
  if (old_id == new_id) {
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnNotificationUpdated(new_id));
  } else {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationRemoved(old_id, false));
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationAdded(new_id));
  }
}

void MessageCenterImpl::RemoveNotification(const std::string& id,
                                           bool by_user) {
  if (!HasNotification(id))
    return;

  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Close(by_user);

  // In many cases |id| is a reference to an existing notification instance
  // but the instance can be destructed in RemoveNotification(). Hence
  // copies the id explicitly here.
  std::string copied_id(id);
  notification_list_->RemoveNotification(copied_id);
  FOR_EACH_OBSERVER(MessageCenterObserver,
                    observer_list_,
                    OnNotificationRemoved(copied_id, by_user));
}

void MessageCenterImpl::RemoveAllNotifications(bool by_user) {
  const NotificationList::Notifications& notifications =
      notification_list_->GetNotifications();
  std::set<std::string> ids;
  for (NotificationList::Notifications::const_iterator iter =
           notifications.begin(); iter != notifications.end(); ++iter) {
    ids.insert((*iter)->id());
    NotificationDelegate* delegate = (*iter)->delegate();
    if (delegate)
      delegate->Close(by_user);
  }
  notification_list_->RemoveAllNotifications();

  for (std::set<std::string>::const_iterator iter = ids.begin();
       iter != ids.end(); ++iter) {
    FOR_EACH_OBSERVER(MessageCenterObserver,
                      observer_list_,
                      OnNotificationRemoved(*iter, by_user));
  }
}

void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
                                        const gfx::Image& image) {
  if (notification_list_->SetNotificationIcon(notification_id, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
                                         const gfx::Image& image) {
  if (notification_list_->SetNotificationImage(notification_id, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::SetNotificationButtonIcon(
    const std::string& notification_id, int button_index,
    const gfx::Image& image) {
  if (!HasNotification(notification_id))
    return;
  if (notification_list_->SetNotificationButtonIcon(notification_id,
                                                    button_index, image)) {
    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                      OnNotificationUpdated(notification_id));
  }
}

void MessageCenterImpl::DisableNotificationsByNotifier(
    const NotifierId& notifier_id) {
  if (settings_provider_) {
    // TODO(mukai): SetNotifierEnabled can just accept notifier_id?
    Notifier notifier(notifier_id, base::string16(), true);
    settings_provider_->SetNotifierEnabled(notifier, false);
  }

  NotificationList::Notifications notifications =
      notification_list_->GetNotificationsByNotifierId(notifier_id);
  for (NotificationList::Notifications::const_iterator iter =
           notifications.begin(); iter != notifications.end();) {
    std::string id = (*iter)->id();
    iter++;
    RemoveNotification(id, false);
  }
}

void MessageCenterImpl::ShowNotificationSettings(const std::string& id) {
  if (delegate_)
    delegate_->ShowSettings(id);
}

void MessageCenterImpl::ExpandNotification(const std::string& id) {
  if (!HasNotification(id))
    return;
  notification_list_->MarkNotificationAsExpanded(id);
  FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
                    OnNotificationUpdated(id));
}

void MessageCenterImpl::ClickOnNotification(const std::string& id) {
  if (!HasNotification(id))
    return;
  if (HasPopupNotifications())
    MarkSinglePopupAsShown(id, true);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Click();
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationClicked(id));
}

void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
                                              int button_index) {
  if (!HasNotification(id))
    return;
  if (HasPopupNotifications())
    MarkSinglePopupAsShown(id, true);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->ButtonClick(button_index);
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationButtonClicked(
          id, button_index));
}

void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
                                               bool mark_notification_as_read) {
  if (!HasNotification(id))
    return;
  notification_list_->MarkSinglePopupAsShown(id, mark_notification_as_read);
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
}

void MessageCenterImpl::DisplayedNotification(const std::string& id) {
  if (!HasNotification(id))
    return;

  if (HasPopupNotifications())
    notification_list_->MarkSinglePopupAsDisplayed(id);
  NotificationDelegate* delegate =
      notification_list_->GetNotificationDelegate(id);
  if (delegate)
    delegate->Display();
  FOR_EACH_OBSERVER(
      MessageCenterObserver, observer_list_, OnNotificationDisplayed(id));
}

void MessageCenterImpl::SetNotifierSettingsProvider(
    NotifierSettingsProvider* provider) {
  settings_provider_ = provider;
}

NotifierSettingsProvider* MessageCenterImpl::GetNotifierSettingsProvider() {
  return settings_provider_;
}

void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
  if (in_quiet_mode != notification_list_->quiet_mode()) {
    notification_list_->SetQuietMode(in_quiet_mode);
    FOR_EACH_OBSERVER(MessageCenterObserver,
                      observer_list_,
                      OnQuietModeChanged(in_quiet_mode));
  }
  quiet_mode_timer_.reset();
}

void MessageCenterImpl::EnterQuietModeWithExpire(
    const base::TimeDelta& expires_in) {
  if (quiet_mode_timer_.get()) {
    // Note that the capital Reset() is the method to restart the timer, not
    // scoped_ptr::reset().
    quiet_mode_timer_->Reset();
  } else {
    notification_list_->SetQuietMode(true);
    FOR_EACH_OBSERVER(
        MessageCenterObserver, observer_list_, OnQuietModeChanged(true));

    quiet_mode_timer_.reset(new base::OneShotTimer<MessageCenterImpl>);
    quiet_mode_timer_->Start(
        FROM_HERE,
        expires_in,
        base::Bind(
            &MessageCenterImpl::SetQuietMode, base::Unretained(this), false));
  }
}

void MessageCenterImpl::RestartPopupTimers() {
  if (popup_timers_controller_.get())
    popup_timers_controller_->StartAll();
}

void MessageCenterImpl::PausePopupTimers() {
  if (popup_timers_controller_.get())
    popup_timers_controller_->PauseAll();
}

void MessageCenterImpl::DisableTimersForTest() {
  popup_timers_controller_.reset();
}

}  // namespace message_center
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: streamwrap.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-23 10:44:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UTL_STREAM_WRAPPER_HXX_
#include <unotools/streamwrap.hxx>
#endif

#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

namespace utl
{

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

//==================================================================
//= OInputStreamWrapper
//==================================================================
DBG_NAME(OInputStreamWrapper)
//------------------------------------------------------------------
OInputStreamWrapper::OInputStreamWrapper( SvStream& _rStream )
                 :m_pSvStream(&_rStream)
                 ,m_bSvStreamOwner(sal_False)
{
    DBG_CTOR(OInputStreamWrapper,NULL);

}

//------------------------------------------------------------------
OInputStreamWrapper::OInputStreamWrapper( SvStream* pStream, sal_Bool bOwner )
                 :m_pSvStream( pStream )
                 ,m_bSvStreamOwner( bOwner )
{
    DBG_CTOR(OInputStreamWrapper,NULL);

}

//------------------------------------------------------------------
OInputStreamWrapper::~OInputStreamWrapper()
{
    if( m_bSvStreamOwner )
        delete m_pSvStream;

    DBG_DTOR(OInputStreamWrapper,NULL);
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
                throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    checkConnected();

    if (nBytesToRead < 0)
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));

    ::osl::MutexGuard aGuard( m_aMutex );

    aData.realloc(nBytesToRead);

    sal_uInt32 nRead = m_pSvStream->Read((void*)aData.getArray(), nBytesToRead);
    checkError();

    // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen
    if (nRead < (sal_uInt32)nBytesToRead)
        aData.realloc( nRead );

    return nRead;
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    checkError();

    if (nMaxBytesToRead < 0)
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));

    if (m_pSvStream->IsEof())
    {
        aData.realloc(0);
        return 0;
    }
    else
        return readBytes(aData, nMaxBytesToRead);
}

//------------------------------------------------------------------------------
void SAL_CALL OInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkError();

#ifdef DBG_UTIL
    sal_uInt32 nCurrentPos = m_pSvStream->Tell();
#endif

    m_pSvStream->SeekRel(nBytesToSkip);
    checkError();

#ifdef DBG_UTIL
    nCurrentPos = m_pSvStream->Tell();
#endif
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nPos = m_pSvStream->Tell();
    checkError();

    m_pSvStream->Seek(STREAM_SEEK_TO_END);
    checkError();

    sal_Int32 nAvailable = (sal_Int32)m_pSvStream->Tell() - nPos;
    m_pSvStream->Seek(nPos);
    checkError();

    return nAvailable;
}

//------------------------------------------------------------------------------
void SAL_CALL OInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    if (m_bSvStreamOwner)
        delete m_pSvStream;

    m_pSvStream = NULL;
}

//------------------------------------------------------------------------------
void OInputStreamWrapper::checkConnected() const
{
    if (!m_pSvStream)
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//------------------------------------------------------------------------------
void OInputStreamWrapper::checkError() const
{
    checkConnected();

    if (m_pSvStream->SvStream::GetError() != ERRCODE_NONE)
        // TODO: really evaluate the error
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//==================================================================
//= OSeekableInputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream& _rStream)
    :OInputStreamWrapper(_rStream)
{
}

//------------------------------------------------------------------------------
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream* _pStream, sal_Bool _bOwner)
    :OInputStreamWrapper(_pStream, _bOwner)
{
}

//------------------------------------------------------------------------------
Any SAL_CALL OSeekableInputStreamWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
{
    Any aReturn = OInputStreamWrapper::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = OSeekableInputStreamWrapper_Base::queryInterface(_rType);
    return aReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableInputStreamWrapper::acquire(  ) throw ()
{
    OInputStreamWrapper::acquire();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableInputStreamWrapper::release(  ) throw ()
{
    OInputStreamWrapper::release();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableInputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    m_pSvStream->Seek((sal_uInt32)_nLocation);
    checkError();
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getPosition(  ) throw (IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nPos = m_pSvStream->Tell();
    checkError();
    return (sal_Int64)nPos;
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getLength(  ) throw (IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nCurrentPos = m_pSvStream->Tell();
    checkError();

    m_pSvStream->Seek(STREAM_SEEK_TO_END);
    sal_uInt32 nEndPos = m_pSvStream->Tell();
    m_pSvStream->Seek(nCurrentPos);

    checkError();

    return (sal_Int64)nEndPos;
}

//==================================================================
//= OOutputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    sal_uInt32 nWritten = rStream.Write(aData.getConstArray(),aData.getLength());
    ErrCode err = rStream.GetError();
    if  (   (ERRCODE_NONE != err)
        ||  (nWritten != (sal_uInt32)aData.getLength())
        )
    {
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
    }
}

//------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    rStream.Flush();
    checkError();
}

//------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
}

//------------------------------------------------------------------------------
void OOutputStreamWrapper::checkError() const
{
    if (rStream.GetError() != ERRCODE_NONE)
        // TODO: really evaluate the error
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//==================================================================
//= OSeekableOutputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
OSeekableOutputStreamWrapper::OSeekableOutputStreamWrapper(SvStream& _rStream)
    :OOutputStreamWrapper(_rStream)
{
}

//------------------------------------------------------------------------------
Any SAL_CALL OSeekableOutputStreamWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
{
    Any aReturn = OOutputStreamWrapper::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = OSeekableOutputStreamWrapper_Base::queryInterface(_rType);
    return aReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::acquire(  ) throw ()
{
    OOutputStreamWrapper::acquire();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::release(  ) throw ()
{
    OOutputStreamWrapper::release();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
{
    rStream.Seek((sal_uInt32)_nLocation);
    checkError();
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getPosition(  ) throw (IOException, RuntimeException)
{
    sal_uInt32 nPos = rStream.Tell();
    checkError();
    return (sal_Int64)nPos;
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getLength(  ) throw (IOException, RuntimeException)
{
    sal_uInt32 nCurrentPos = rStream.Tell();
    checkError();

    rStream.Seek(STREAM_SEEK_TO_END);
    sal_uInt32 nEndPos = rStream.Tell();
    rStream.Seek(nCurrentPos);

    checkError();

    return (sal_Int64)nEndPos;
}

} // namespace utl

<commit_msg>INTEGRATION: CWS mav09 (1.3.142); FILE MERGED 2004/08/09 18:59:35 mav 1.3.142.3: RESYNC: (1.3-1.4); FILE MERGED 2004/05/16 17:29:55 mba 1.3.142.2: #i27773#: XTruncate needed 2004/04/30 08:00:30 mba 1.3.142.1: #i27773#: wrapper for XStream<commit_after>/*************************************************************************
 *
 *  $RCSfile: streamwrap.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2004-10-04 20:29:57 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _UTL_STREAM_WRAPPER_HXX_
#include <unotools/streamwrap.hxx>
#endif

#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

namespace utl
{

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

//==================================================================
//= OInputStreamWrapper
//==================================================================
DBG_NAME(OInputStreamWrapper)
//------------------------------------------------------------------
OInputStreamWrapper::OInputStreamWrapper( SvStream& _rStream )
                 :m_pSvStream(&_rStream)
                 ,m_bSvStreamOwner(sal_False)
{
    DBG_CTOR(OInputStreamWrapper,NULL);

}

//------------------------------------------------------------------
OInputStreamWrapper::OInputStreamWrapper( SvStream* pStream, sal_Bool bOwner )
                 :m_pSvStream( pStream )
                 ,m_bSvStreamOwner( bOwner )
{
    DBG_CTOR(OInputStreamWrapper,NULL);

}

//------------------------------------------------------------------
OInputStreamWrapper::~OInputStreamWrapper()
{
    if( m_bSvStreamOwner )
        delete m_pSvStream;

    DBG_DTOR(OInputStreamWrapper,NULL);
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
                throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    checkConnected();

    if (nBytesToRead < 0)
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));

    ::osl::MutexGuard aGuard( m_aMutex );

    aData.realloc(nBytesToRead);

    sal_uInt32 nRead = m_pSvStream->Read((void*)aData.getArray(), nBytesToRead);
    checkError();

    // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen
    if (nRead < (sal_uInt32)nBytesToRead)
        aData.realloc( nRead );

    return nRead;
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    checkError();

    if (nMaxBytesToRead < 0)
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));

    if (m_pSvStream->IsEof())
    {
        aData.realloc(0);
        return 0;
    }
    else
        return readBytes(aData, nMaxBytesToRead);
}

//------------------------------------------------------------------------------
void SAL_CALL OInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkError();

#ifdef DBG_UTIL
    sal_uInt32 nCurrentPos = m_pSvStream->Tell();
#endif

    m_pSvStream->SeekRel(nBytesToSkip);
    checkError();

#ifdef DBG_UTIL
    nCurrentPos = m_pSvStream->Tell();
#endif
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL OInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nPos = m_pSvStream->Tell();
    checkError();

    m_pSvStream->Seek(STREAM_SEEK_TO_END);
    checkError();

    sal_Int32 nAvailable = (sal_Int32)m_pSvStream->Tell() - nPos;
    m_pSvStream->Seek(nPos);
    checkError();

    return nAvailable;
}

//------------------------------------------------------------------------------
void SAL_CALL OInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    if (m_bSvStreamOwner)
        delete m_pSvStream;

    m_pSvStream = NULL;
}

//------------------------------------------------------------------------------
void OInputStreamWrapper::checkConnected() const
{
    if (!m_pSvStream)
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//------------------------------------------------------------------------------
void OInputStreamWrapper::checkError() const
{
    checkConnected();

    if (m_pSvStream->SvStream::GetError() != ERRCODE_NONE)
        // TODO: really evaluate the error
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//==================================================================
//= OSeekableInputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream& _rStream)
{
    SetStream( &_rStream, FALSE );
}

//------------------------------------------------------------------------------
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream* _pStream, sal_Bool _bOwner)
{
    SetStream( _pStream, _bOwner );
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableInputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    m_pSvStream->Seek((sal_uInt32)_nLocation);
    checkError();
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getPosition(  ) throw (IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nPos = m_pSvStream->Tell();
    checkError();
    return (sal_Int64)nPos;
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getLength(  ) throw (IOException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkConnected();

    sal_uInt32 nCurrentPos = m_pSvStream->Tell();
    checkError();

    m_pSvStream->Seek(STREAM_SEEK_TO_END);
    sal_uInt32 nEndPos = m_pSvStream->Tell();
    m_pSvStream->Seek(nCurrentPos);

    checkError();

    return (sal_Int64)nEndPos;
}

//==================================================================
//= OOutputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    sal_uInt32 nWritten = rStream.Write(aData.getConstArray(),aData.getLength());
    ErrCode err = rStream.GetError();
    if  (   (ERRCODE_NONE != err)
        ||  (nWritten != (sal_uInt32)aData.getLength())
        )
    {
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
    }
}

//------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
    rStream.Flush();
    checkError();
}

//------------------------------------------------------------------
void SAL_CALL OOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
{
}

//------------------------------------------------------------------------------
void OOutputStreamWrapper::checkError() const
{
    if (rStream.GetError() != ERRCODE_NONE)
        // TODO: really evaluate the error
        throw stario::NotConnectedException(::rtl::OUString(), const_cast<staruno::XWeak*>(static_cast<const staruno::XWeak*>(this)));
}

//==================================================================
//= OSeekableOutputStreamWrapper
//==================================================================
//------------------------------------------------------------------------------
OSeekableOutputStreamWrapper::OSeekableOutputStreamWrapper(SvStream& _rStream)
    :OOutputStreamWrapper(_rStream)
{
}

//------------------------------------------------------------------------------
Any SAL_CALL OSeekableOutputStreamWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
{
    Any aReturn = OOutputStreamWrapper::queryInterface(_rType);
    if (!aReturn.hasValue())
        aReturn = OSeekableOutputStreamWrapper_Base::queryInterface(_rType);
    return aReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::acquire(  ) throw ()
{
    OOutputStreamWrapper::acquire();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::release(  ) throw ()
{
    OOutputStreamWrapper::release();
}

//------------------------------------------------------------------------------
void SAL_CALL OSeekableOutputStreamWrapper::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
{
    rStream.Seek((sal_uInt32)_nLocation);
    checkError();
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getPosition(  ) throw (IOException, RuntimeException)
{
    sal_uInt32 nPos = rStream.Tell();
    checkError();
    return (sal_Int64)nPos;
}

//------------------------------------------------------------------------------
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getLength(  ) throw (IOException, RuntimeException)
{
    sal_uInt32 nCurrentPos = rStream.Tell();
    checkError();

    rStream.Seek(STREAM_SEEK_TO_END);
    sal_uInt32 nEndPos = rStream.Tell();
    rStream.Seek(nCurrentPos);

    checkError();

    return (sal_Int64)nEndPos;
}

//------------------------------------------------------------------------------
OStreamWrapper::OStreamWrapper(SvStream& _rStream)
{
    SetStream( &_rStream, FALSE );
}

//------------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL OStreamWrapper::getInputStream(  ) throw (::com::sun::star::uno::RuntimeException)
{
    return this;
}

//------------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL OStreamWrapper::getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException)
{
    return this;
}

//------------------------------------------------------------------------------
void SAL_CALL OStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException)
{
    sal_uInt32 nWritten = m_pSvStream->Write(aData.getConstArray(),aData.getLength());
    ErrCode err = m_pSvStream->GetError();
    if  (   (ERRCODE_NONE != err)
        ||  (nWritten != (sal_uInt32)aData.getLength())
        )
    {
        throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
    }
}

//------------------------------------------------------------------------------
void SAL_CALL OStreamWrapper::flush() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException)
{
    m_pSvStream->Flush();
    if (m_pSvStream->GetError() != ERRCODE_NONE)
        throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
}

//------------------------------------------------------------------------------
void SAL_CALL OStreamWrapper::closeOutput() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException)
{
}

//------------------------------------------------------------------------------
void SAL_CALL OStreamWrapper::truncate() throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
    m_pSvStream->SetStreamSize(0);
}

} // namespace utl

<|endoftext|>


<commit_before>#include "extractor.h"

#include <cassert>
#include <map>
#include <vector>

#include "taco/base/exception.h"

#include "tools-common/relation/relation.h"

namespace taco {
namespace tool {
namespace m3 {

void Extractor::Extract(Tree &t, std::set<Relation> &relations,
                        std::vector<std::string> &warnings) {
  relation_vec_.clear();
  node_to_relation_.clear();

  // Visit nodes extracting noun-modifier agreement relations.
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    Extract(**p, warnings);
  }

  // Add relations to output set.
  for (RelationVec::const_iterator p = relation_vec_.begin();
       p != relation_vec_.end(); ++p) {
    relations.insert(**p);
  }

  // Mop up any unclaimed modifiers and nouns to produce single-word
  // selector-target sets.  Whilst those selectors / targets don't participate
  // in an agreement relation in this particular parse tree, the rules they
  // end up in may become part of a derivation where there is such a relation.
  std::vector<Tree *> leaves;
  t.GetLeaves(leaves);
  for (std::vector<Tree *>::const_iterator p = leaves.begin();
       p != leaves.end(); ++p) {
    Tree *leaf = *p;
    // Already in a relation?
    if (node_to_relation_.find(leaf) != node_to_relation_.end()) {
      continue;
    }
    Tree *preterminal = leaf->parent();
    if (IsNoCm(*preterminal) || IsModifier(*preterminal)) {
      Relation r;
      AddNodeToRelation(*preterminal, r);
      AddNodeToRelation(*leaf, r);
      relations.insert(r);
    }
  }
}

void Extractor::Extract(Tree &t, std::vector<std::string> &warnings) {
  // Recursively visit children first.
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    Extract(**p, warnings);
  }

  // Check if this is a common noun.
  if (!IsNoCm(t)) {
    return;
  }

  // Look for the closest sibling to the left.
  Tree *left_sibling = ClosestLeftSibling(t);
  if (!left_sibling) {
    return;
  }

  // If the sibling is also a common noun then ignore this noun.  Any modifiers
  // to the left will agree with that noun, not this one.
  if (IsNoCm(*left_sibling)) {
    return;
  }

  // Create a new relation.
  boost::shared_ptr<Relation> r(new Relation());
  relation_vec_.push_back(r);

  // Add the noun.
  AddNodeToRelation(t, *r);
  AddNodeToRelation(*(t.GetChild(0)), *r);

  // Add the parent node.
  AddNodeToRelation(*(t.parent()), *r);

  // Add any Det / Aj siblings to the relation, terminating after the first Det.
  while (true) {
    if (IsDet(*left_sibling)) {
      try {
        AddUnaryChainToRelation(*left_sibling, *r);
      } catch(const Exception &e) {
        std::ostringstream msg;
        msg << "failed to add Det chain to relation: " << e.msg();
        warnings.push_back(msg.str());
      }
      break;
    }
    if (DominatesAj(*left_sibling)) {
      AddAjSubtreeToRelation(*left_sibling, *r);
    }
    left_sibling = ClosestLeftSibling(*left_sibling);
    if (!left_sibling) {
      break;
    }
  }
}

bool Extractor::IsAj(const Tree &t) {
  return t.IsPreterminal() && t.label().get<kIdxCat>() == "Aj";
}

bool Extractor::IsNoCm(const Tree &t) {
  return t.IsPreterminal() && t.label().get<kIdxCat>() == "NoCm";
}

bool Extractor::IsModifier(const Tree &t) {
  if (!t.IsPreterminal()) {
    return false;
  }
  const std::string &cat = t.label().get<kIdxCat>();
  return cat == "Aj" || cat == "AtDf" || cat == "AtId";
}

bool Extractor::IsDet(const Tree &t) {
  if (t.IsLeaf() || t.IsPreterminal()) {
    return false;
  }
  return t.label().get<kIdxCat>() == "Det";
}

bool Extractor::DominatesAj(const Tree &t) {
  if (t.IsLeaf() || t.IsPreterminal()) {
    return false;
  }
  const std::vector<Tree *> &children = t.children();
  return children.size() == 1 && IsAj(*t.GetChild(0));
}

// Return a pointer to the sibling immediately to the left of t or 0 if none.
Tree *Extractor::ClosestLeftSibling(const Tree &t) {
  const Tree *parent = t.parent();
  if (!parent) {
    return 0;
  }
  // Find t's position among its siblings.
  const std::vector<Tree *> &siblings = parent->children();
  std::size_t i = 0;
  for (; i < siblings.size(); ++i) {
    if (siblings[i] == &t) {
      break;
    }
  }
  // Is t the leftmost sibling?
  if (i == 0) {
    return 0;
  }
  // Return a pointer to the previous sibling.
  return siblings[i-1];
}

void Extractor::AddNodeToRelation(Tree &t, Relation &r) {
  r.nodes.insert(&t);
  node_to_relation_[&t] = &r;
}

void Extractor::AddUnaryChainToRelation(Tree &t, Relation &r) {
  const std::vector<Tree *> &children = t.children();
  if (children.size() > 1) {
    throw Exception("unary chain is not unary");
  }
  if (children.size() == 1) {
    AddUnaryChainToRelation(*children[0], r);
  }
  r.nodes.insert(&t);
  node_to_relation_[&t] = &r;
}

void Extractor::AddAjSubtreeToRelation(Tree &t, Relation &r) {
  AddNodeToRelation(t, r);
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    if (IsAj(**p)) {
      AddNodeToRelation(t, r);
      AddNodeToRelation(*(t.GetChild(0)), r);
    }
  }
}

}  // namespace m3
}  // namespace tool
}  // namespace taco
<commit_msg>m3-label-st-sets: fix labelling bug<commit_after>#include "extractor.h"

#include <cassert>
#include <map>
#include <vector>

#include "taco/base/exception.h"

#include "tools-common/relation/relation.h"

namespace taco {
namespace tool {
namespace m3 {

void Extractor::Extract(Tree &t, std::set<Relation> &relations,
                        std::vector<std::string> &warnings) {
  relation_vec_.clear();
  node_to_relation_.clear();

  // Visit nodes extracting noun-modifier agreement relations.
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    Extract(**p, warnings);
  }

  // Add relations to output set.
  for (RelationVec::const_iterator p = relation_vec_.begin();
       p != relation_vec_.end(); ++p) {
    relations.insert(**p);
  }

  // Mop up any unclaimed modifiers and nouns to produce single-word
  // selector-target sets.  Whilst those selectors / targets don't participate
  // in an agreement relation in this particular parse tree, the rules they
  // end up in may become part of a derivation where there is such a relation.
  std::vector<Tree *> leaves;
  t.GetLeaves(leaves);
  for (std::vector<Tree *>::const_iterator p = leaves.begin();
       p != leaves.end(); ++p) {
    Tree *leaf = *p;
    // Already in a relation?
    if (node_to_relation_.find(leaf) != node_to_relation_.end()) {
      continue;
    }
    Tree *preterminal = leaf->parent();
    if (IsNoCm(*preterminal) || IsModifier(*preterminal)) {
      Relation r;
      AddNodeToRelation(*preterminal, r);
      AddNodeToRelation(*leaf, r);
      relations.insert(r);
    }
  }
}

void Extractor::Extract(Tree &t, std::vector<std::string> &warnings) {
  // Recursively visit children first.
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    Extract(**p, warnings);
  }

  // Check if this is a common noun.
  if (!IsNoCm(t)) {
    return;
  }

  // Look for the closest sibling to the left.
  Tree *left_sibling = ClosestLeftSibling(t);
  if (!left_sibling) {
    return;
  }

  // If the sibling is also a common noun then ignore this noun.  Any modifiers
  // to the left will agree with that noun, not this one.
  if (IsNoCm(*left_sibling)) {
    return;
  }

  // Create a new relation.
  boost::shared_ptr<Relation> r(new Relation());
  relation_vec_.push_back(r);

  // Add the noun.
  AddNodeToRelation(t, *r);
  AddNodeToRelation(*(t.GetChild(0)), *r);

  // Add the parent node.
  AddNodeToRelation(*(t.parent()), *r);

  // Add any Det / Aj siblings to the relation, terminating after the first Det.
  while (true) {
    if (IsDet(*left_sibling)) {
      try {
        AddUnaryChainToRelation(*left_sibling, *r);
      } catch(const Exception &e) {
        std::ostringstream msg;
        msg << "failed to add Det chain to relation: " << e.msg();
        warnings.push_back(msg.str());
      }
      break;
    }
    if (DominatesAj(*left_sibling)) {
      AddAjSubtreeToRelation(*left_sibling, *r);
    }
    left_sibling = ClosestLeftSibling(*left_sibling);
    if (!left_sibling) {
      break;
    }
  }
}

bool Extractor::IsAj(const Tree &t) {
  return t.IsPreterminal() && t.label().get<kIdxCat>() == "Aj";
}

bool Extractor::IsNoCm(const Tree &t) {
  return t.IsPreterminal() && t.label().get<kIdxCat>() == "NoCm";
}

bool Extractor::IsModifier(const Tree &t) {
  if (!t.IsPreterminal()) {
    return false;
  }
  const std::string &cat = t.label().get<kIdxCat>();
  return cat == "Aj" || cat == "AtDf" || cat == "AtId";
}

bool Extractor::IsDet(const Tree &t) {
  if (t.IsLeaf() || t.IsPreterminal()) {
    return false;
  }
  return t.label().get<kIdxCat>() == "Det";
}

bool Extractor::DominatesAj(const Tree &t) {
  if (t.IsLeaf() || t.IsPreterminal()) {
    return false;
  }
  const std::vector<Tree *> &children = t.children();
  return children.size() == 1 && IsAj(*t.GetChild(0));
}

// Return a pointer to the sibling immediately to the left of t or 0 if none.
Tree *Extractor::ClosestLeftSibling(const Tree &t) {
  const Tree *parent = t.parent();
  if (!parent) {
    return 0;
  }
  // Find t's position among its siblings.
  const std::vector<Tree *> &siblings = parent->children();
  std::size_t i = 0;
  for (; i < siblings.size(); ++i) {
    if (siblings[i] == &t) {
      break;
    }
  }
  // Is t the leftmost sibling?
  if (i == 0) {
    return 0;
  }
  // Return a pointer to the previous sibling.
  return siblings[i-1];
}

void Extractor::AddNodeToRelation(Tree &t, Relation &r) {
  r.nodes.insert(&t);
  node_to_relation_[&t] = &r;
}

void Extractor::AddUnaryChainToRelation(Tree &t, Relation &r) {
  const std::vector<Tree *> &children = t.children();
  if (children.size() > 1) {
    throw Exception("unary chain is not unary");
  }
  if (children.size() == 1) {
    AddUnaryChainToRelation(*children[0], r);
  }
  r.nodes.insert(&t);
  node_to_relation_[&t] = &r;
}

void Extractor::AddAjSubtreeToRelation(Tree &t, Relation &r) {
  AddNodeToRelation(t, r);
  for (std::vector<Tree *>::const_iterator p = t.children().begin();
       p != t.children().end(); ++p) {
    Tree *child = *p;
    if (IsAj(*child)) {
      AddNodeToRelation(*child, r);
      AddNodeToRelation(*(child->GetChild(0)), r);
    }
  }
}

}  // namespace m3
}  // namespace tool
}  // namespace taco
<|endoftext|>


<commit_before>/*!
      A simple Fortran 77 interface

 This file is an example of how to write an interface to use Cantera
 in Fortran 77 programs. The basic idea is to store pointers to
 Cantera objects in global storage, and then create Fortran-callable
 functions that access the objects through the pointers.

 This particular example defines functions that return thermodynamic
 properties, transport properties, and kinetic rates for reacting
 ideal gas mixtures. Only a single pointer to an IdealGasMix object is
 stored, so only one reaction mechanism may be used at any one time in
 the application.  Of course, it is a simple modification to store
 multiple objects if it is desired to use multiple reaction
 mechanisms.

 The functions defined here are ones commonly needed in application
 programs that simulate gas-phase combustion or similar
 processes. Similar libraries to access other capabilities of Cantera
 (surface chemistry, etc.) could be written in the same way.

 This library is designed for Fortran compilers that expect external
 procedure na,es to be lowercase with a trailing underscore. If this
 is not the case, the procedure names must be edited before use.

 */

// turn off warnings under Windows
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

// add any other Cantera header files you need here
#include <cantera/Cantera.h>
#include <cantera/IdealGasMix.h>

using namespace Cantera;
using namespace Cantera_CXX;

// store a pointer to an IdealGasMix object
static IdealGasMix* _gas = 0;

// provides access to the pointers for functions in other libraries
IdealGasMix* _gasptr() { return _gas; }

// comment these out to produce a smaller executable if not needed
#define WITH_EQUIL
#define WITH_TRANSPORT

#ifdef WITH_EQUIL
#include <cantera/equilibrium.h>
#endif

#ifdef WITH_TRANSPORT
#include <cantera/transport.h>

// store a pointer to a transport manager
static Transport* _trans = 0;
Transport* _transptr() { return _trans; }
#endif

// error handler
void handleError() {
    showErrors(cout);
    exit(-1);
}

// extern "C" turns off C++ name-mangling, so that the procedure names
// in the object file are exactly as shown here.

extern "C" {

    /// This is the Fortran main program. This works for g77; it may
    /// need to be modified for other Fortran compilers
#ifdef NEED_ALT_MAIN
    extern int MAIN__();
#endif

    /**
     * Read in a reaction mechanism file and create an IdealGasMix
     * object. The file may be in Cantera input format or in CTML. (If
     * you have a file in Chemkin-compatible format, use utility
     * program ck2cti first to convert it into Cantera format.)
     */
    void newidealgasmix_(char* file, char* id, char* transport,
        ftnlen lenfile, ftnlen lenid, ftnlen lentr) {
        string trmodel = "";
        try {
            string fin = string(file, lenfile);
            string fth = string(id, lenid);
            trmodel = string(transport, lentr);
            if (_gas) delete _gas;
            _gas = new IdealGasMix(fin, fth);
        }
        catch (CanteraError) {
            handleError();
        }
#ifdef WITH_TRANSPORT
        try {
            if (_trans) delete _trans;
            _trans = newTransportMgr(trmodel,_gas,1);
        }
        catch (CanteraError) {
            _trans =  newTransportMgr("",_gas,1);
        }
#endif
    }

    ///   integer function nElements()
    integer nelements_() { return _gas->nElements(); }

    /// integer function nSpecies()
    integer nspecies_() { return _gas->nSpecies(); }

    /// integer function nReactions()
    integer nreactions_() { return _gas->nReactions(); }

    void getspeciesname_(integer* k, char* name, ftnlen n) {
        int ik = *k - 1;
        fill(name, name + n, ' ');
        string spnm = _gas->speciesName(ik);
        int ns = spnm.size();
        unsigned int nmx = (ns > n ? n : ns);
        copy(spnm.begin(), spnm.begin()+nmx, name);
    }

    //-------------- setting the state ----------------------------

    /// subroutine setState_TPX(T, P, X)
    void setstate_tpx_(doublereal* T, doublereal* P, doublereal* X) {
        try {
            _gas->setState_TPX(*T, *P, X);
        }
        catch (CanteraError) { handleError(); }
    }

    /// subroutine setState_TPX_String(T, P, X)
    void setstate_tpx_string_(doublereal* T, doublereal* P,
        char* X, ftnlen lenx) {
        try {
            _gas->setState_TPX(*T, *P, string(X, lenx));
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_try_(doublereal* T, doublereal* rho, doublereal* Y) {
        try {
            _gas->setState_TRY(*T, *rho, Y);
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_tpy_(doublereal* T, doublereal* p, doublereal* Y) {
        try {
            _gas->setState_TPY(*T, *p, Y);
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_sp_(doublereal* s, doublereal* p) {
        try {
            _gas->setState_SP(*s, *p);
        }
        catch (CanteraError) { handleError(); }
    }

    //-------------- thermodynamic properties ----------------------

    /// Temperature (K)
    doublereal temperature_() {
        return _gas->temperature();
    }

    /// Pressure (Pa)
    doublereal pressure_() {
        return _gas->pressure();
    }

    /// Density (kg/m^3)
    doublereal density_() {
        return _gas->density();
    }

    /// Mean molar mass (kg/kmol).
    doublereal meanmolarmass_() {
        return _gas->meanMolecularWeight();
    }

    /// Molar enthalpy (J/kmol)
    doublereal enthalpy_mole_() {
        return _gas->enthalpy_mole();
    }

    /// Molar internal energy (J/kmol)
    doublereal intenergy_mole_() {
        return _gas->intEnergy_mole();
    }

    /// Molar entropy (J/kmol-K)
    doublereal entropy_mole_() {
        return _gas->entropy_mole();
    }

    /// Molar heat capacity at constant P (J/kmol-K)
    doublereal cp_mole_() {
        return _gas->cp_mole();
    }

    /// Molar Gibbs function (J/kmol)
    doublereal gibbs_mole_() {
        return _gas->gibbs_mole();
    }

    doublereal enthalpy_mass_() {
        return _gas->enthalpy_mass();
    }

    doublereal intenergy_mass_() {
        return _gas->intEnergy_mass();
    }

    doublereal entropy_mass_() {
        return _gas->entropy_mass();
    }

    doublereal cp_mass_() {
        return _gas->cp_mass();
    }

    doublereal cv_mass_() {
        return _gas->cv_mass();
    }

    doublereal gibbs_mass_() {
        return _gas->gibbs_mass();
    }

    void gotmolefractions_(doublereal* x) {
        _gas->getMoleFractions(x);
    }

    void gotmassfractions_(doublereal* y) {
        _gas->getMassFractions(y);
    }

#ifdef WITH_EQUIL
    void equilibrate_(char* opt, ftnlen lenopt) {
        try {
            if (lenopt != 2) {
                throw CanteraError("equilibrate",
                    "two-character string required.");
            }
            string optstr = string(opt, 2);
            equilibrate(*_gas, optstr.c_str());
        }
        catch (CanteraError) { handleError(); }
    }
#endif

    //---------------- kinetics -------------------------

    void getreactioneqn_(integer* i, char* eqn, ftnlen n) {
        int irxn = *i - 1;
        fill(eqn, eqn + n, ' ');
        string e = _gas->reactionString(irxn);
        int ns = e.size();
        unsigned int nmx = (ns > n ? n : ns);
        copy(e.begin(), e.begin()+nmx, eqn);
    }

    void getnetproductionrates_(doublereal* wdot) {
        _gas->getNetProductionRates(wdot);
    }

    void getcreationrates_(doublereal* cdot) {
        _gas->getCreationRates(cdot);
    }

    void getdestructionrates_(doublereal* ddot) {
        _gas->getDestructionRates(ddot);
    }

    void getnetratesofprogress_(doublereal* q) {
        _gas->getNetRatesOfProgress(q);
    }

    void getfwdratesofprogress_(doublereal* q) {
        _gas->getFwdRatesOfProgress(q);
    }

    void getrevratesofprogress_(doublereal* q) {
        _gas->getRevRatesOfProgress(q);
    }

    //-------------------- transport properties --------------------

#ifdef WITH_TRANSPORT
    double viscosity_() {
        try {
            return _trans->viscosity();
        }
        catch (CanteraError) { handleError(); return 0.0; }
    }

    double thermalconductivity_() {
        try {
            return _trans->thermalConductivity();
        }
        catch (CanteraError) { handleError(); return 0.0; }
    }

    void getmixdiffcoeffs_(double* diff) {
        try {
            _trans->getMixDiffCoeffs(diff);
        }
        catch (CanteraError) { handleError();}
    }

    void getthermaldiffcoeffs_(double* dt) {
        try {
            _trans->getThermalDiffCoeffs(dt);
        }
        catch (CanteraError) { handleError();}
    }
#endif

}

/*
 *  HKM 7/22/09:
 *    I'm skeptical that you need this for any system.
 *    Definately creates an error (dupl main()) for the solaris
 *    system
 */
#ifdef NEED_ALT_MAIN
/**
 * This C++ main program simply calls the Fortran main program.
 */
int main() {
    try {
        return MAIN__();
    }
    catch (CanteraError) {
        showErrors(cerr);
        exit(-1);
    }
    catch (...) {
        cout << "An exception was trapped. Program terminating." << endl;
        exit(-1);
    }
}
#endif
<commit_msg>Added namespace to get it to compile<commit_after>/*!
      A simple Fortran 77 interface

 This file is an example of how to write an interface to use Cantera
 in Fortran 77 programs. The basic idea is to store pointers to
 Cantera objects in global storage, and then create Fortran-callable
 functions that access the objects through the pointers.

 This particular example defines functions that return thermodynamic
 properties, transport properties, and kinetic rates for reacting
 ideal gas mixtures. Only a single pointer to an IdealGasMix object is
 stored, so only one reaction mechanism may be used at any one time in
 the application.  Of course, it is a simple modification to store
 multiple objects if it is desired to use multiple reaction
 mechanisms.

 The functions defined here are ones commonly needed in application
 programs that simulate gas-phase combustion or similar
 processes. Similar libraries to access other capabilities of Cantera
 (surface chemistry, etc.) could be written in the same way.

 This library is designed for Fortran compilers that expect external
 procedure na,es to be lowercase with a trailing underscore. If this
 is not the case, the procedure names must be edited before use.

 */

// turn off warnings under Windows
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

// add any other Cantera header files you need here
#include <cantera/Cantera.h>
#include <cantera/IdealGasMix.h>

using namespace Cantera;
using namespace Cantera_CXX;
using namespace std;

// store a pointer to an IdealGasMix object
static IdealGasMix* _gas = 0;

// provides access to the pointers for functions in other libraries
IdealGasMix* _gasptr() { return _gas; }

// comment these out to produce a smaller executable if not needed
#define WITH_EQUIL
#define WITH_TRANSPORT

#ifdef WITH_EQUIL
#include <cantera/equilibrium.h>
#endif

#ifdef WITH_TRANSPORT
#include <cantera/transport.h>

// store a pointer to a transport manager
static Transport* _trans = 0;
Transport* _transptr() { return _trans; }
#endif

// error handler
void handleError() {
    showErrors(cout);
    exit(-1);
}

// extern "C" turns off C++ name-mangling, so that the procedure names
// in the object file are exactly as shown here.

extern "C" {

    /// This is the Fortran main program. This works for g77; it may
    /// need to be modified for other Fortran compilers
#ifdef NEED_ALT_MAIN
    extern int MAIN__();
#endif

    /**
     * Read in a reaction mechanism file and create an IdealGasMix
     * object. The file may be in Cantera input format or in CTML. (If
     * you have a file in Chemkin-compatible format, use utility
     * program ck2cti first to convert it into Cantera format.)
     */
    void newidealgasmix_(char* file, char* id, char* transport,
        ftnlen lenfile, ftnlen lenid, ftnlen lentr) {
        string trmodel = "";
        try {
            string fin = string(file, lenfile);
            string fth = string(id, lenid);
            trmodel = string(transport, lentr);
            if (_gas) delete _gas;
            _gas = new IdealGasMix(fin, fth);
        }
        catch (CanteraError) {
            handleError();
        }
#ifdef WITH_TRANSPORT
        try {
            if (_trans) delete _trans;
            _trans = newTransportMgr(trmodel,_gas,1);
        }
        catch (CanteraError) {
            _trans =  newTransportMgr("",_gas,1);
        }
#endif
    }

    ///   integer function nElements()
    integer nelements_() { return _gas->nElements(); }

    /// integer function nSpecies()
    integer nspecies_() { return _gas->nSpecies(); }

    /// integer function nReactions()
    integer nreactions_() { return _gas->nReactions(); }

    void getspeciesname_(integer* k, char* name, ftnlen n) {
        int ik = *k - 1;
        fill(name, name + n, ' ');
        string spnm = _gas->speciesName(ik);
        int ns = spnm.size();
        unsigned int nmx = (ns > n ? n : ns);
        copy(spnm.begin(), spnm.begin()+nmx, name);
    }

    //-------------- setting the state ----------------------------

    /// subroutine setState_TPX(T, P, X)
    void setstate_tpx_(doublereal* T, doublereal* P, doublereal* X) {
        try {
            _gas->setState_TPX(*T, *P, X);
        }
        catch (CanteraError) { handleError(); }
    }

    /// subroutine setState_TPX_String(T, P, X)
    void setstate_tpx_string_(doublereal* T, doublereal* P,
        char* X, ftnlen lenx) {
        try {
            _gas->setState_TPX(*T, *P, string(X, lenx));
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_try_(doublereal* T, doublereal* rho, doublereal* Y) {
        try {
            _gas->setState_TRY(*T, *rho, Y);
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_tpy_(doublereal* T, doublereal* p, doublereal* Y) {
        try {
            _gas->setState_TPY(*T, *p, Y);
        }
        catch (CanteraError) { handleError(); }
    }

    void setstate_sp_(doublereal* s, doublereal* p) {
        try {
            _gas->setState_SP(*s, *p);
        }
        catch (CanteraError) { handleError(); }
    }

    //-------------- thermodynamic properties ----------------------

    /// Temperature (K)
    doublereal temperature_() {
        return _gas->temperature();
    }

    /// Pressure (Pa)
    doublereal pressure_() {
        return _gas->pressure();
    }

    /// Density (kg/m^3)
    doublereal density_() {
        return _gas->density();
    }

    /// Mean molar mass (kg/kmol).
    doublereal meanmolarmass_() {
        return _gas->meanMolecularWeight();
    }

    /// Molar enthalpy (J/kmol)
    doublereal enthalpy_mole_() {
        return _gas->enthalpy_mole();
    }

    /// Molar internal energy (J/kmol)
    doublereal intenergy_mole_() {
        return _gas->intEnergy_mole();
    }

    /// Molar entropy (J/kmol-K)
    doublereal entropy_mole_() {
        return _gas->entropy_mole();
    }

    /// Molar heat capacity at constant P (J/kmol-K)
    doublereal cp_mole_() {
        return _gas->cp_mole();
    }

    /// Molar Gibbs function (J/kmol)
    doublereal gibbs_mole_() {
        return _gas->gibbs_mole();
    }

    doublereal enthalpy_mass_() {
        return _gas->enthalpy_mass();
    }

    doublereal intenergy_mass_() {
        return _gas->intEnergy_mass();
    }

    doublereal entropy_mass_() {
        return _gas->entropy_mass();
    }

    doublereal cp_mass_() {
        return _gas->cp_mass();
    }

    doublereal cv_mass_() {
        return _gas->cv_mass();
    }

    doublereal gibbs_mass_() {
        return _gas->gibbs_mass();
    }

    void gotmolefractions_(doublereal* x) {
        _gas->getMoleFractions(x);
    }

    void gotmassfractions_(doublereal* y) {
        _gas->getMassFractions(y);
    }

#ifdef WITH_EQUIL
    void equilibrate_(char* opt, ftnlen lenopt) {
        try {
            if (lenopt != 2) {
                throw CanteraError("equilibrate",
                    "two-character string required.");
            }
            string optstr = string(opt, 2);
            equilibrate(*_gas, optstr.c_str());
        }
        catch (CanteraError) { handleError(); }
    }
#endif

    //---------------- kinetics -------------------------

    void getreactioneqn_(integer* i, char* eqn, ftnlen n) {
        int irxn = *i - 1;
        fill(eqn, eqn + n, ' ');
        string e = _gas->reactionString(irxn);
        int ns = e.size();
        unsigned int nmx = (ns > n ? n : ns);
        copy(e.begin(), e.begin()+nmx, eqn);
    }

    void getnetproductionrates_(doublereal* wdot) {
        _gas->getNetProductionRates(wdot);
    }

    void getcreationrates_(doublereal* cdot) {
        _gas->getCreationRates(cdot);
    }

    void getdestructionrates_(doublereal* ddot) {
        _gas->getDestructionRates(ddot);
    }

    void getnetratesofprogress_(doublereal* q) {
        _gas->getNetRatesOfProgress(q);
    }

    void getfwdratesofprogress_(doublereal* q) {
        _gas->getFwdRatesOfProgress(q);
    }

    void getrevratesofprogress_(doublereal* q) {
        _gas->getRevRatesOfProgress(q);
    }

    //-------------------- transport properties --------------------

#ifdef WITH_TRANSPORT
    double viscosity_() {
        try {
            return _trans->viscosity();
        }
        catch (CanteraError) { handleError(); return 0.0; }
    }

    double thermalconductivity_() {
        try {
            return _trans->thermalConductivity();
        }
        catch (CanteraError) { handleError(); return 0.0; }
    }

    void getmixdiffcoeffs_(double* diff) {
        try {
            _trans->getMixDiffCoeffs(diff);
        }
        catch (CanteraError) { handleError();}
    }

    void getthermaldiffcoeffs_(double* dt) {
        try {
            _trans->getThermalDiffCoeffs(dt);
        }
        catch (CanteraError) { handleError();}
    }
#endif

}

/*
 *  HKM 7/22/09:
 *    I'm skeptical that you need this for any system.
 *    Definately creates an error (dupl main()) for the solaris
 *    system
 */
#ifdef NEED_ALT_MAIN
/**
 * This C++ main program simply calls the Fortran main program.
 */
int main() {
    try {
        return MAIN__();
    }
    catch (CanteraError) {
        showErrors(cerr);
        exit(-1);
    }
    catch (...) {
        cout << "An exception was trapped. Program terminating." << endl;
        exit(-1);
    }
}
#endif
<|endoftext|>


<commit_before>// check sanity of vsx aligned ld/st
// https://github.com/opencv/opencv/issues/13211

#include <altivec.h>

#define vsx_ld vec_vsx_ld
#define vsx_st vec_vsx_st

template<typename T>
static void fill(T& d, int from = 0, int to = 16)
{
   for (int i = from; i < to; i++)
        d[i] = i;
}

template<typename T, typename Tvec>
static bool check_data(T& d, Tvec& v, int from = 0, int to = 16)
{
    for (int i = from; i < to; i++)
    {
        if (d[i] != vec_extract(v, i))
            return false;
    }
    return true;
}

int main()
{
    unsigned char __attribute__ ((aligned (16))) rbuf[16];
    unsigned char __attribute__ ((aligned (16))) wbuf[16];
    __vector unsigned char a;

    // 1- check aligned load and store
    fill(rbuf);
    a = vec_ld(0, rbuf);
    if (!check_data(rbuf, a))
        return 1;
    vec_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 11;

    // 2- check mixing aligned load and unaligned store
    a = vec_ld(0, rbuf);
    vsx_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 2;

    // 3- check mixing unaligned load and aligned store
    a = vsx_ld(0, rbuf);
    vec_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 3;

    return 0;
}<commit_msg>cmake:vsx Fix compilation fail on aligned runtime test when c++11 enabled<commit_after>// check sanity of vsx aligned ld/st
// https://github.com/opencv/opencv/issues/13211

#include <altivec.h>
#undef bool

#define vsx_ld vec_vsx_ld
#define vsx_st vec_vsx_st

template<typename T>
static void fill(T& d, int from = 0, int to = 16)
{
   for (int i = from; i < to; i++)
        d[i] = i;
}

template<typename T, typename Tvec>
static bool check_data(T& d, Tvec& v, int from = 0, int to = 16)
{
    for (int i = from; i < to; i++)
    {
        if (d[i] != vec_extract(v, i))
            return false;
    }
    return true;
}

int main()
{
    unsigned char __attribute__ ((aligned (16))) rbuf[16];
    unsigned char __attribute__ ((aligned (16))) wbuf[16];
    __vector unsigned char a;

    // 1- check aligned load and store
    fill(rbuf);
    a = vec_ld(0, rbuf);
    if (!check_data(rbuf, a))
        return 1;
    vec_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 11;

    // 2- check mixing aligned load and unaligned store
    a = vec_ld(0, rbuf);
    vsx_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 2;

    // 3- check mixing unaligned load and aligned store
    a = vsx_ld(0, rbuf);
    vec_st(a, 0, wbuf);
    if (!check_data(wbuf, a))
        return 3;

    return 0;
}<|endoftext|>