<commit_before>// Copyright (c) 2012 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 "chrome/browser/extensions/extension_disabled_ui.h"

#include <string>

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_uninstall_dialog.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/global_error.h"
#include "chrome/browser/ui/global_error_service.h"
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

static base::LazyInstance<
    std::bitset<IDC_EXTENSION_DISABLED_LAST -
                IDC_EXTENSION_DISABLED_FIRST + 1> >
    menu_command_ids = LAZY_INSTANCE_INITIALIZER;

// Get an available menu ID.
int GetMenuCommandID() {
  int id;
  for (id = IDC_EXTENSION_DISABLED_FIRST;
       id <= IDC_EXTENSION_DISABLED_LAST; ++id) {
    if (!menu_command_ids.Get()[id - IDC_EXTENSION_DISABLED_FIRST]) {
      menu_command_ids.Get().set(id - IDC_EXTENSION_DISABLED_FIRST);
      return id;
    }
  }
  // This should not happen.
  DCHECK(id <= IDC_EXTENSION_DISABLED_LAST) <<
      "No available menu command IDs for ExtensionDisabledGlobalError";
  return IDC_EXTENSION_DISABLED_LAST;
}

// Make a menu ID available when it is no longer used.
void ReleaseMenuCommandID(int id) {
  menu_command_ids.Get().reset(id - IDC_EXTENSION_DISABLED_FIRST);
}

}  // namespace

// ExtensionDisabledDialogDelegate --------------------------------------------

class ExtensionDisabledDialogDelegate
    : public ExtensionInstallUI::Delegate,
      public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> {
 public:
  ExtensionDisabledDialogDelegate(Profile* profile,
                                  ExtensionService* service,
                                  const Extension* extension);

 private:
  friend class base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate>;

  virtual ~ExtensionDisabledDialogDelegate();

  // ExtensionInstallUI::Delegate:
  virtual void InstallUIProceed() OVERRIDE;
  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;

  // The UI for showing the install dialog when enabling.
  scoped_ptr<ExtensionInstallUI> install_ui_;

  ExtensionService* service_;
  const Extension* extension_;
};

ExtensionDisabledDialogDelegate::ExtensionDisabledDialogDelegate(
    Profile* profile,
    ExtensionService* service,
    const Extension* extension)
    : service_(service), extension_(extension) {
  AddRef();  // Balanced in Proceed or Abort.

  install_ui_.reset(new ExtensionInstallUI(profile));
  install_ui_->ConfirmReEnable(this, extension_);
}

ExtensionDisabledDialogDelegate::~ExtensionDisabledDialogDelegate() {
}

void ExtensionDisabledDialogDelegate::InstallUIProceed() {
  service_->GrantPermissionsAndEnableExtension(extension_);
  Release();
}

void ExtensionDisabledDialogDelegate::InstallUIAbort(bool user_initiated) {
  std::string histogram_name = user_initiated ?
      "Extensions.Permissions_ReEnableCancel" :
      "Extensions.Permissions_ReEnableAbort";
  ExtensionService::RecordPermissionMessagesHistogram(
      extension_, histogram_name.c_str());

  // Do nothing. The extension will remain disabled.
  Release();
}

// ExtensionDisabledGlobalError -----------------------------------------------

class ExtensionDisabledGlobalError : public GlobalError,
                                     public content::NotificationObserver,
                                     public ExtensionUninstallDialog::Delegate {
 public:
  ExtensionDisabledGlobalError(ExtensionService* service,
                               const Extension* extension);
  virtual ~ExtensionDisabledGlobalError();

  // GlobalError implementation.
  virtual bool HasBadge() OVERRIDE;
  virtual bool HasMenuItem() OVERRIDE;
  virtual int MenuItemCommandID() OVERRIDE;
  virtual string16 MenuItemLabel() OVERRIDE;
  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
  virtual bool HasBubbleView() OVERRIDE;
  virtual string16 GetBubbleViewTitle() OVERRIDE;
  virtual string16 GetBubbleViewMessage() OVERRIDE;
  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;

  // ExtensionUninstallDialog::Delegate implementation.
  virtual void ExtensionUninstallAccepted() OVERRIDE;
  virtual void ExtensionUninstallCanceled() OVERRIDE;

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

 private:
  ExtensionService* service_;
  const Extension* extension_;

  scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_;

  // Menu command ID assigned for this extension's error.
  int menu_command_id_;

  content::NotificationRegistrar registrar_;
};

// TODO(yoz): create error at startup for disabled extensions.
ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
    ExtensionService* service,
    const Extension* extension)
    : service_(service),
      extension_(extension),
      menu_command_id_(GetMenuCommandID()) {
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                 content::Source<Profile>(service->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
                 content::Source<Profile>(service->profile()));
}

ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
}

bool ExtensionDisabledGlobalError::HasBadge() {
  return true;
}

bool ExtensionDisabledGlobalError::HasMenuItem() {
  return true;
}

int ExtensionDisabledGlobalError::MenuItemCommandID() {
  return menu_command_id_;
}

string16 ExtensionDisabledGlobalError::MenuItemLabel() {
  return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
                                    UTF8ToUTF16(extension_->name()));
}

void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) {
  ShowBubbleView(browser);
}

bool ExtensionDisabledGlobalError::HasBubbleView() {
   return true;
}

string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() {
  return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
                                    UTF8ToUTF16(extension_->name()));
}

string16 ExtensionDisabledGlobalError::GetBubbleViewMessage() {
  return l10n_util::GetStringFUTF16(extension_->is_app() ?
      IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL,
      UTF8ToUTF16(extension_->name()));
}

string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() {
  return l10n_util::GetStringUTF16(
      IDS_EXTENSION_DISABLED_ERROR_ENABLE_BUTTON);
}

string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() {
  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL);
}

void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) {
}

void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed(
    Browser* browser) {
  new ExtensionDisabledDialogDelegate(service_->profile(), service_,
                                      extension_);
}

void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed(
    Browser* browser) {
  uninstall_dialog_.reset(
      ExtensionUninstallDialog::Create(service_->profile(), this));
  uninstall_dialog_->ConfirmUninstall(extension_);
}

void ExtensionDisabledGlobalError::ExtensionUninstallAccepted() {
  service_->UninstallExtension(extension_->id(), false, NULL);
}

void ExtensionDisabledGlobalError::ExtensionUninstallCanceled() {
  // Nothing happens, and the error is still there.
}

void ExtensionDisabledGlobalError::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  const Extension* extension = NULL;
  // The error is invalidated if the extension has been reloaded
  // or unloaded.
  if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
    extension = content::Details<const Extension>(details).ptr();
  } else {
    DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
    UnloadedExtensionInfo* info =
        content::Details<UnloadedExtensionInfo>(details).ptr();
    extension = info->extension;
  }
  if (extension == extension_) {
    GlobalErrorServiceFactory::GetForProfile(service_->profile())->
        RemoveGlobalError(this);
    ReleaseMenuCommandID(menu_command_id_);
    delete this;
  }
}

// Globals --------------------------------------------------------------------

namespace extensions {

void ShowExtensionDisabledUI(ExtensionService* service,
                             Profile* profile,
                             const Extension* extension) {
  GlobalErrorServiceFactory::GetForProfile(service->profile())->
      AddGlobalError(new ExtensionDisabledGlobalError(service, extension));
}

void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
                                 const Extension* extension) {
  // This object manages its own lifetime.
  new ExtensionDisabledDialogDelegate(profile, service, extension);
}

}  // namespace extensions
<commit_msg>Add histogram for user actions in response to the extension disabled error.<commit_after>// Copyright (c) 2012 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 "chrome/browser/extensions/extension_disabled_ui.h"

#include <string>

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_uninstall_dialog.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/global_error.h"
#include "chrome/browser/ui/global_error_service.h"
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

static base::LazyInstance<
    std::bitset<IDC_EXTENSION_DISABLED_LAST -
                IDC_EXTENSION_DISABLED_FIRST + 1> >
    menu_command_ids = LAZY_INSTANCE_INITIALIZER;

// Get an available menu ID.
int GetMenuCommandID() {
  int id;
  for (id = IDC_EXTENSION_DISABLED_FIRST;
       id <= IDC_EXTENSION_DISABLED_LAST; ++id) {
    if (!menu_command_ids.Get()[id - IDC_EXTENSION_DISABLED_FIRST]) {
      menu_command_ids.Get().set(id - IDC_EXTENSION_DISABLED_FIRST);
      return id;
    }
  }
  // This should not happen.
  DCHECK(id <= IDC_EXTENSION_DISABLED_LAST) <<
      "No available menu command IDs for ExtensionDisabledGlobalError";
  return IDC_EXTENSION_DISABLED_LAST;
}

// Make a menu ID available when it is no longer used.
void ReleaseMenuCommandID(int id) {
  menu_command_ids.Get().reset(id - IDC_EXTENSION_DISABLED_FIRST);
}

}  // namespace

// ExtensionDisabledDialogDelegate --------------------------------------------

class ExtensionDisabledDialogDelegate
    : public ExtensionInstallUI::Delegate,
      public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> {
 public:
  ExtensionDisabledDialogDelegate(Profile* profile,
                                  ExtensionService* service,
                                  const Extension* extension);

 private:
  friend class base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate>;

  virtual ~ExtensionDisabledDialogDelegate();

  // ExtensionInstallUI::Delegate:
  virtual void InstallUIProceed() OVERRIDE;
  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;

  // The UI for showing the install dialog when enabling.
  scoped_ptr<ExtensionInstallUI> install_ui_;

  ExtensionService* service_;
  const Extension* extension_;
};

ExtensionDisabledDialogDelegate::ExtensionDisabledDialogDelegate(
    Profile* profile,
    ExtensionService* service,
    const Extension* extension)
    : service_(service), extension_(extension) {
  AddRef();  // Balanced in Proceed or Abort.

  install_ui_.reset(new ExtensionInstallUI(profile));
  install_ui_->ConfirmReEnable(this, extension_);
}

ExtensionDisabledDialogDelegate::~ExtensionDisabledDialogDelegate() {
}

void ExtensionDisabledDialogDelegate::InstallUIProceed() {
  service_->GrantPermissionsAndEnableExtension(extension_);
  Release();
}

void ExtensionDisabledDialogDelegate::InstallUIAbort(bool user_initiated) {
  std::string histogram_name = user_initiated ?
      "Extensions.Permissions_ReEnableCancel" :
      "Extensions.Permissions_ReEnableAbort";
  ExtensionService::RecordPermissionMessagesHistogram(
      extension_, histogram_name.c_str());

  // Do nothing. The extension will remain disabled.
  Release();
}

// ExtensionDisabledGlobalError -----------------------------------------------

class ExtensionDisabledGlobalError : public GlobalError,
                                     public content::NotificationObserver,
                                     public ExtensionUninstallDialog::Delegate {
 public:
  ExtensionDisabledGlobalError(ExtensionService* service,
                               const Extension* extension);
  virtual ~ExtensionDisabledGlobalError();

  // GlobalError implementation.
  virtual bool HasBadge() OVERRIDE;
  virtual bool HasMenuItem() OVERRIDE;
  virtual int MenuItemCommandID() OVERRIDE;
  virtual string16 MenuItemLabel() OVERRIDE;
  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
  virtual bool HasBubbleView() OVERRIDE;
  virtual string16 GetBubbleViewTitle() OVERRIDE;
  virtual string16 GetBubbleViewMessage() OVERRIDE;
  virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
  virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
  virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
  virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
  virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;

  // ExtensionUninstallDialog::Delegate implementation.
  virtual void ExtensionUninstallAccepted() OVERRIDE;
  virtual void ExtensionUninstallCanceled() OVERRIDE;

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

 private:
  ExtensionService* service_;
  const Extension* extension_;

  // How the user responded to the error; used for metrics.
  enum UserResponse {
    IGNORED,
    REENABLE,
    UNINSTALL,
    EXTENSION_DISABLED_UI_BUCKET_BOUNDARY
  };
  UserResponse user_response_;

  scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_;

  // Menu command ID assigned for this extension's error.
  int menu_command_id_;

  content::NotificationRegistrar registrar_;
};

// TODO(yoz): create error at startup for disabled extensions.
ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
    ExtensionService* service,
    const Extension* extension)
    : service_(service),
      extension_(extension),
      user_response_(IGNORED),
      menu_command_id_(GetMenuCommandID()) {
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                 content::Source<Profile>(service->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
                 content::Source<Profile>(service->profile()));
}

ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
  HISTOGRAM_ENUMERATION("Extension.DisabledUIUserResponse",
                        user_response_, EXTENSION_DISABLED_UI_BUCKET_BOUNDARY);
}

bool ExtensionDisabledGlobalError::HasBadge() {
  return true;
}

bool ExtensionDisabledGlobalError::HasMenuItem() {
  return true;
}

int ExtensionDisabledGlobalError::MenuItemCommandID() {
  return menu_command_id_;
}

string16 ExtensionDisabledGlobalError::MenuItemLabel() {
  return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
                                    UTF8ToUTF16(extension_->name()));
}

void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) {
  ShowBubbleView(browser);
}

bool ExtensionDisabledGlobalError::HasBubbleView() {
   return true;
}

string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() {
  return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
                                    UTF8ToUTF16(extension_->name()));
}

string16 ExtensionDisabledGlobalError::GetBubbleViewMessage() {
  return l10n_util::GetStringFUTF16(extension_->is_app() ?
      IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL,
      UTF8ToUTF16(extension_->name()));
}

string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() {
  return l10n_util::GetStringUTF16(
      IDS_EXTENSION_DISABLED_ERROR_ENABLE_BUTTON);
}

string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() {
  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL);
}

void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) {
}

void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed(
    Browser* browser) {
  new ExtensionDisabledDialogDelegate(service_->profile(), service_,
                                      extension_);
}

void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed(
    Browser* browser) {
  uninstall_dialog_.reset(
      ExtensionUninstallDialog::Create(service_->profile(), this));
  uninstall_dialog_->ConfirmUninstall(extension_);
}

void ExtensionDisabledGlobalError::ExtensionUninstallAccepted() {
  service_->UninstallExtension(extension_->id(), false, NULL);
}

void ExtensionDisabledGlobalError::ExtensionUninstallCanceled() {
  // Nothing happens, and the error is still there.
}

void ExtensionDisabledGlobalError::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  const Extension* extension = NULL;
  // The error is invalidated if the extension has been reloaded
  // or unloaded.
  if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
    extension = content::Details<const Extension>(details).ptr();
  } else {
    DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
    UnloadedExtensionInfo* info =
        content::Details<UnloadedExtensionInfo>(details).ptr();
    extension = info->extension;
  }
  if (extension == extension_) {
    GlobalErrorServiceFactory::GetForProfile(service_->profile())->
        RemoveGlobalError(this);
    ReleaseMenuCommandID(menu_command_id_);

    if (type == chrome::NOTIFICATION_EXTENSION_LOADED)
      user_response_ = REENABLE;
    else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED)
      user_response_ = UNINSTALL;
    delete this;
  }
}

// Globals --------------------------------------------------------------------

namespace extensions {

void ShowExtensionDisabledUI(ExtensionService* service,
                             Profile* profile,
                             const Extension* extension) {
  GlobalErrorServiceFactory::GetForProfile(service->profile())->
      AddGlobalError(new ExtensionDisabledGlobalError(service, extension));
}

void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
                                 const Extension* extension) {
  // This object manages its own lifetime.
  new ExtensionDisabledDialogDelegate(profile, service, extension);
}

}  // namespace extensions
<|endoftext|>


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

#define ZORBA_DEBUG_ICU_STREAMBUF 0

#ifdef ZORBA_DEBUG_ICU_STREAMBUF
# include <stdio.h>
#endif

#include <algorithm>
#include <cassert>

#include <zorba/diagnostic_list.h>

#include "diagnostics/assert.h"
#include "diagnostics/diagnostic.h"
#include "diagnostics/zorba_exception.h"
#include "util/cxx_util.h"
#include "util/string_util.h"
#include "util/utf8_util.h"

#include "icu_streambuf.h"

using namespace std;

namespace zorba {

int const Small_External_Buf_Size = 6;
int const Large_External_Buf_Size = 4096;

///////////////////////////////////////////////////////////////////////////////

inline void icu_streambuf::buf_type_base::reset() {
  pivot_source_ = pivot_target_ = pivot_buf_;
}

inline void icu_streambuf::resetg() {
  setg(
    g_.utf8_char_, g_.utf8_char_ + sizeof g_.utf8_char_,
    g_.utf8_char_ + sizeof g_.utf8_char_
  );
}

icu_streambuf::icu_streambuf( char const *charset, streambuf *orig ) :
  proxy_streambuf( orig ),
  no_conv_( !is_necessary( charset ) ),
  external_conv_( no_conv_ ? nullptr : create_conv( charset ) ),
  utf8_conv_( no_conv_ ? nullptr : create_conv( "UTF-8" ) )
{
  if ( !orig )
    throw invalid_argument( "null streambuf" );
  resetg();
}

icu_streambuf::~icu_streambuf() {
  if ( external_conv_ )
    ucnv_close( external_conv_ );
  if ( utf8_conv_ )
    ucnv_close( utf8_conv_ );
}

void icu_streambuf::clear() {
  if ( !no_conv_ ) {
    ucnv_reset( external_conv_ );
    ucnv_reset( utf8_conv_ );
    g_.reset();
    p_.reset();
    resetg();
  }
}

UConverter* icu_streambuf::create_conv( char const *charset ) {
  UErrorCode err = U_ZERO_ERROR;
  UConverter *const conv = ucnv_open( charset, &err );
  ucnv_setFromUCallBack(
    conv, UCNV_FROM_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err
  );
  ucnv_setToUCallBack(
    conv, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err
  );
  if ( !conv || U_FAILURE( err ) ) {
    if ( conv )
      ucnv_close( conv );
    throw invalid_argument( charset );
  }
  return conv;
}

bool icu_streambuf::is_necessary( char const *charset ) {
  //
  // Checking for "US-ASCII" explicitly isn't necessary since ICU knows about
  // aliases.
  //
  return  !ucnv_compareNames( charset, "ASCII" )
      &&  !ucnv_compareNames( charset, "UTF-8" );
}

bool icu_streambuf::is_supported( char const *charset ) {
  try {
    ucnv_close( create_conv( charset ) );
    return true;
  }
  catch ( invalid_argument const& ) {
    return false;
  }
}

icu_streambuf::pos_type icu_streambuf::seekoff( off_type o, ios_base::seekdir d,
                                                ios_base::openmode m ) {
  clear();
  return original()->pubseekoff( o, d, m );
}

icu_streambuf::pos_type icu_streambuf::seekpos( pos_type p,
                                                ios_base::openmode m ) {
  clear();
  return original()->pubseekpos( p, m );
}

streambuf* icu_streambuf::setbuf( char_type *p, streamsize s ) {
  original()->pubsetbuf( p, s );
  return this;
}

int icu_streambuf::sync() {
  return original()->pubsync();
}

icu_streambuf::int_type icu_streambuf::overflow( int_type c ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "overflow()\n" );
#endif
  if ( no_conv_ )
    return original()->sputc( c );

  if ( traits_type::eq_int_type( c, traits_type::eof() ) )
    return traits_type::eof();

  char_type const utf8_byte = traits_type::to_char_type( c );
  char_type const *from = &utf8_byte;
  char ebuf[ Small_External_Buf_Size ], *to = ebuf;

  bool const ok = to_external( &from, from + 1, &to, to + sizeof ebuf );
  assert( ok );
  if ( streamsize const n = to - ebuf ) {
    original()->sputn( ebuf, n );
    p_.reset();
  }

  return c;
}

bool icu_streambuf::to_external( char_type const **from,
                                 char_type const *from_end, char **to,
                                 char const *to_end, bool flush ) {
  UErrorCode err = U_ZERO_ERROR;
  ucnv_convertEx(
    external_conv_, utf8_conv_, to, to_end, from, from_end,
    p_.pivot_buf_, &p_.pivot_source_, &p_.pivot_target_,
    p_.pivot_buf_ + sizeof p_.pivot_buf_,
    /*reset*/ false, flush, &err
  );
  if ( err == U_TRUNCATED_CHAR_FOUND || err == U_BUFFER_OVERFLOW_ERROR )
    return false;
  if ( U_FAILURE( err ) )
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0006_TRANSCODING_ERROR, ERROR_PARAMS( u_errorName( err ) )
    );
  return true;
}

bool icu_streambuf::to_utf8( char const **from, char const *from_end,
                             char_type **to, char_type const *to_end,
                             bool flush ) {
  UErrorCode err = U_ZERO_ERROR;
  ucnv_convertEx(
    utf8_conv_, external_conv_, to, to_end, from, from_end,
    g_.pivot_buf_, &g_.pivot_source_, &g_.pivot_target_,
    g_.pivot_buf_ + sizeof g_.pivot_buf_,
    /*reset*/ false, flush, &err
  );
  if ( err == U_TRUNCATED_CHAR_FOUND || err == U_BUFFER_OVERFLOW_ERROR )
    return false;
  if ( U_FAILURE( err ) )
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0006_TRANSCODING_ERROR, ERROR_PARAMS( u_errorName( err ) )
    );
  return true;
}

icu_streambuf::int_type icu_streambuf::underflow() {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "underflow()\n" );
#endif
  if ( no_conv_ )
    return original()->sgetc();

  if ( gptr() >= egptr() ) {
    utf8::storage_type *to = g_.utf8_char_;
    utf8::storage_type const *const to_end = to + sizeof g_.utf8_char_;

    while ( true ) {
      int_type const c = original()->sbumpc();
      if ( traits_type::eq_int_type( c, traits_type::eof() ) )
        return traits_type::eof();

      char const ebyte = traits_type::to_char_type( c );
      char const *from = &ebyte;

      to_utf8( &from, from + 1, &to, to_end );
      if ( to > g_.utf8_char_ ) {
        setg( g_.utf8_char_, g_.utf8_char_, to );
        g_.reset();
        break;
      }
    }
  }
  return traits_type::to_int_type( *gptr() );
}

streamsize icu_streambuf::xsgetn( char_type *to, streamsize size ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "xsgetn()\n" );
#endif
  if ( no_conv_ )
    return original()->sgetn( to, size );

  streamsize return_size = 0;
  char_type *const to_end = to + size;

  if ( streamsize const gsize = egptr() - gptr() ) {
    // must first get any chars in g_.utf8_char_
    streamsize const n = min( gsize, size );
    traits_type::copy( to, gptr(), n );
    gbump( n );
    to += n;
    size -= n, return_size += n;
  }

  while ( size > 0 ) {
    char ebuf[ Large_External_Buf_Size ];
    streamsize const get = min( (streamsize)(sizeof ebuf), size );
    if ( streamsize const got = original()->sgetn( ebuf, get ) ) {
      char const *from = ebuf;
      char_type const *const to_orig = to;
      int_type const peek = original()->sgetc();
      bool const flush = traits_type::eq_int_type( peek, traits_type::eof() );
      to_utf8( &from, from + got, &to, to_end, flush );
      streamsize const n = to - to_orig;
      size -= n, return_size += n;
      if ( flush )
        break;
    } else
      break;
  }
  return return_size;
}

streamsize icu_streambuf::xsputn( char_type const *from, streamsize size ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "xsputn()\n" );
#endif
  if ( no_conv_ )
    return original()->sputn( from, size );

  streamsize return_size = 0;
  char_type const *const from_end = from + size;
  char ebuf[ Large_External_Buf_Size ], *to = ebuf;
  char const *const to_end = to + sizeof ebuf;

  while ( size > 0 ) {
    char_type const *const from_orig = from;
    to_external( &from, from_end, &to, to_end );
    streamsize n = to - ebuf;
    if ( n && !original()->sputn( ebuf, n ) )
      break;
    to = ebuf;
    n = from - from_orig;
    size -= n, return_size += n;
  }
  return return_size;
}

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<commit_msg>Fixed is_necessary().<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define ZORBA_DEBUG_ICU_STREAMBUF 0

#ifdef ZORBA_DEBUG_ICU_STREAMBUF
# include <stdio.h>
#endif

#include <algorithm>
#include <cassert>

#include <zorba/diagnostic_list.h>

#include "diagnostics/assert.h"
#include "diagnostics/diagnostic.h"
#include "diagnostics/zorba_exception.h"
#include "util/cxx_util.h"
#include "util/string_util.h"
#include "util/utf8_util.h"

#include "icu_streambuf.h"

using namespace std;

namespace zorba {

int const Small_External_Buf_Size = 6;
int const Large_External_Buf_Size = 4096;

///////////////////////////////////////////////////////////////////////////////

inline void icu_streambuf::buf_type_base::reset() {
  pivot_source_ = pivot_target_ = pivot_buf_;
}

inline void icu_streambuf::resetg() {
  setg(
    g_.utf8_char_, g_.utf8_char_ + sizeof g_.utf8_char_,
    g_.utf8_char_ + sizeof g_.utf8_char_
  );
}

icu_streambuf::icu_streambuf( char const *charset, streambuf *orig ) :
  proxy_streambuf( orig ),
  no_conv_( !is_necessary( charset ) ),
  external_conv_( no_conv_ ? nullptr : create_conv( charset ) ),
  utf8_conv_( no_conv_ ? nullptr : create_conv( "UTF-8" ) )
{
  if ( !orig )
    throw invalid_argument( "null streambuf" );
  resetg();
}

icu_streambuf::~icu_streambuf() {
  if ( external_conv_ )
    ucnv_close( external_conv_ );
  if ( utf8_conv_ )
    ucnv_close( utf8_conv_ );
}

void icu_streambuf::clear() {
  if ( !no_conv_ ) {
    ucnv_reset( external_conv_ );
    ucnv_reset( utf8_conv_ );
    g_.reset();
    p_.reset();
    resetg();
  }
}

UConverter* icu_streambuf::create_conv( char const *charset ) {
  UErrorCode err = U_ZERO_ERROR;
  UConverter *const conv = ucnv_open( charset, &err );
  ucnv_setFromUCallBack(
    conv, UCNV_FROM_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err
  );
  ucnv_setToUCallBack(
    conv, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err
  );
  if ( !conv || U_FAILURE( err ) ) {
    if ( conv )
      ucnv_close( conv );
    throw invalid_argument( charset );
  }
  return conv;
}

bool icu_streambuf::is_necessary( char const *charset ) {
  //
  // Checking for "US-ASCII" explicitly isn't necessary since ICU knows about
  // aliases.
  //
  return  ucnv_compareNames( charset, "ASCII" )
      &&  ucnv_compareNames( charset, "UTF-8" );
}

bool icu_streambuf::is_supported( char const *charset ) {
  try {
    ucnv_close( create_conv( charset ) );
    return true;
  }
  catch ( invalid_argument const& ) {
    return false;
  }
}

icu_streambuf::pos_type icu_streambuf::seekoff( off_type o, ios_base::seekdir d,
                                                ios_base::openmode m ) {
  clear();
  return original()->pubseekoff( o, d, m );
}

icu_streambuf::pos_type icu_streambuf::seekpos( pos_type p,
                                                ios_base::openmode m ) {
  clear();
  return original()->pubseekpos( p, m );
}

streambuf* icu_streambuf::setbuf( char_type *p, streamsize s ) {
  original()->pubsetbuf( p, s );
  return this;
}

int icu_streambuf::sync() {
  return original()->pubsync();
}

icu_streambuf::int_type icu_streambuf::overflow( int_type c ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "overflow()\n" );
#endif
  if ( no_conv_ )
    return original()->sputc( c );

  if ( traits_type::eq_int_type( c, traits_type::eof() ) )
    return traits_type::eof();

  char_type const utf8_byte = traits_type::to_char_type( c );
  char_type const *from = &utf8_byte;
  char ebuf[ Small_External_Buf_Size ], *to = ebuf;

  bool const ok = to_external( &from, from + 1, &to, to + sizeof ebuf );
  assert( ok );
  if ( streamsize const n = to - ebuf ) {
    original()->sputn( ebuf, n );
    p_.reset();
  }

  return c;
}

bool icu_streambuf::to_external( char_type const **from,
                                 char_type const *from_end, char **to,
                                 char const *to_end, bool flush ) {
  UErrorCode err = U_ZERO_ERROR;
  ucnv_convertEx(
    external_conv_, utf8_conv_, to, to_end, from, from_end,
    p_.pivot_buf_, &p_.pivot_source_, &p_.pivot_target_,
    p_.pivot_buf_ + sizeof p_.pivot_buf_,
    /*reset*/ false, flush, &err
  );
  if ( err == U_TRUNCATED_CHAR_FOUND || err == U_BUFFER_OVERFLOW_ERROR )
    return false;
  if ( U_FAILURE( err ) )
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0006_TRANSCODING_ERROR, ERROR_PARAMS( u_errorName( err ) )
    );
  return true;
}

bool icu_streambuf::to_utf8( char const **from, char const *from_end,
                             char_type **to, char_type const *to_end,
                             bool flush ) {
  UErrorCode err = U_ZERO_ERROR;
  ucnv_convertEx(
    utf8_conv_, external_conv_, to, to_end, from, from_end,
    g_.pivot_buf_, &g_.pivot_source_, &g_.pivot_target_,
    g_.pivot_buf_ + sizeof g_.pivot_buf_,
    /*reset*/ false, flush, &err
  );
  if ( err == U_TRUNCATED_CHAR_FOUND || err == U_BUFFER_OVERFLOW_ERROR )
    return false;
  if ( U_FAILURE( err ) )
    throw ZORBA_EXCEPTION(
      zerr::ZOSE0006_TRANSCODING_ERROR, ERROR_PARAMS( u_errorName( err ) )
    );
  return true;
}

icu_streambuf::int_type icu_streambuf::underflow() {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "underflow()\n" );
#endif
  if ( no_conv_ )
    return original()->sgetc();

  if ( gptr() >= egptr() ) {
    utf8::storage_type *to = g_.utf8_char_;
    utf8::storage_type const *const to_end = to + sizeof g_.utf8_char_;

    while ( true ) {
      int_type const c = original()->sbumpc();
      if ( traits_type::eq_int_type( c, traits_type::eof() ) )
        return traits_type::eof();

      char const ebyte = traits_type::to_char_type( c );
      char const *from = &ebyte;

      to_utf8( &from, from + 1, &to, to_end );
      if ( to > g_.utf8_char_ ) {
        setg( g_.utf8_char_, g_.utf8_char_, to );
        g_.reset();
        break;
      }
    }
  }
  return traits_type::to_int_type( *gptr() );
}

streamsize icu_streambuf::xsgetn( char_type *to, streamsize size ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "xsgetn()\n" );
#endif
  if ( no_conv_ )
    return original()->sgetn( to, size );

  streamsize return_size = 0;
  char_type *const to_end = to + size;

  if ( streamsize const gsize = egptr() - gptr() ) {
    // must first get any chars in g_.utf8_char_
    streamsize const n = min( gsize, size );
    traits_type::copy( to, gptr(), n );
    gbump( n );
    to += n;
    size -= n, return_size += n;
  }

  while ( size > 0 ) {
    char ebuf[ Large_External_Buf_Size ];
    streamsize const get = min( (streamsize)(sizeof ebuf), size );
    if ( streamsize const got = original()->sgetn( ebuf, get ) ) {
      char const *from = ebuf;
      char_type const *const to_orig = to;
      int_type const peek = original()->sgetc();
      bool const flush = traits_type::eq_int_type( peek, traits_type::eof() );
      to_utf8( &from, from + got, &to, to_end, flush );
      streamsize const n = to - to_orig;
      size -= n, return_size += n;
      if ( flush )
        break;
    } else
      break;
  }
  return return_size;
}

streamsize icu_streambuf::xsputn( char_type const *from, streamsize size ) {
#if ZORBA_DEBUG_ICU_STREAMBUF
  printf( "xsputn()\n" );
#endif
  if ( no_conv_ )
    return original()->sputn( from, size );

  streamsize return_size = 0;
  char_type const *const from_end = from + size;
  char ebuf[ Large_External_Buf_Size ], *to = ebuf;
  char const *const to_end = to + sizeof ebuf;

  while ( size > 0 ) {
    char_type const *const from_orig = from;
    to_external( &from, from_end, &to, to_end );
    streamsize n = to - ebuf;
    if ( n && !original()->sputn( ebuf, n ) )
      break;
    to = ebuf;
    n = from - from_orig;
    size -= n, return_size += n;
  }
  return return_size;
}

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<|endoftext|>


<commit_before><commit_msg>Refactor index value capture outside of DCHECK to fix build failure in release.<commit_after><|endoftext|>


<commit_before>// $Id: DCDFile_test.C,v 1.1 2000/12/19 13:25:13 anker Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////

// insert includes here
#include <BALL/FORMAT/DCDFile.h>
#include <BALL/MOLMEC/MDSIMULATION/molecularDynamics.h>

///////////////////////////

START_TEST(class_name, "$Id: DCDFile_test.C,v 1.1 2000/12/19 13:25:13 anker Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

///  insert tests for each member function here
///

CHECK(DCDHeader::DCDHeader())
	// BAUSTELLE
RESULT

CHECK(DCDHeader::operator << (os, header))
	// BAUSTELLE
RESULT

CHECK(DCDHeader::operator >> (os, header))
	// BAUSTELLE
RESULT

CHECK(DCDFile::DCDFile())
	// BAUSTELLE
RESULT

CHECK(DCDFile::DCDFile(const DCDFile& file))
	// BAUSTELLE
RESULT

CHECK(DCDFile::DCDFile(const String& name, File::OpenMode open_mode))
	// BAUSTELLE
RESULT

CHECK(DCDFile::~DCDFile)
	// BAUSTELLE
RESULT

CHECK(DCDFile::operator = (const DCDFile& file))
	// BAUSTELLE
RESULT

CHECK(DCDFile::clear())
	// BAUSTELLE
RESULT

CHECK(DCDFile::operator == (const DCDFile& file))
	// BAUSTELLE
RESULT

CHECK(DCDFile::readHeader())
	// BAUSTELLE
RESULT

CHECK(DCDFile::updateHeader(const SnapShotManager& manager))
	// BAUSTELLE
RESULT

CHECK(DCDFile::writeHeader())
	// BAUSTELLE
RESULT

CHECK(DCDFile::read(SnapShotManager& manager))
	// BAUSTELLE
RESULT

CHECK(DCDFile::write(const SnapShotManager& manager))
	// BAUSTELLE
RESULT

CHECK(DCDFile::append(const SnapShot& snapshot))
	// BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>added some trivial tests<commit_after>// $Id: DCDFile_test.C,v 1.2 2001/03/28 13:00:55 anker Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////

// insert includes here
#include <BALL/FORMAT/DCDFile.h>

///////////////////////////

START_TEST(class_name, "$Id: DCDFile_test.C,v 1.2 2001/03/28 13:00:55 anker Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

///  insert tests for each member function here

String dcd_test_file("data/DCD_test.dcd");

CHECK(DCDFile::DCDHeader::DCDHeader() throw())
  DCDFile::DCDHeader* p = new DCDFile::DCDHeader;
	TEST_NOT_EQUAL(p, 0)
RESULT

DCDFile* p = new DCDFile;

CHECK(DCDFile::DCDFile() throw())
  p = new DCDFile;
	TEST_NOT_EQUAL(p, 0)
RESULT

CHECK(DCDFile::~DCDFile() throw())
	delete p;
RESULT

CHECK(DCDFile::DCDFile(const DCDFile& file) throw())
  DCDFile first_file;
	DCDFile second_file(first_file);
	bool test = (first_file == second_file);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::DCDFile(const String& name, File::OpenMode open_mode) throw())
  //BAUSTELLE
  DCDFile test_file(dcd_test_file, File::IN);
	TEST_EQUAL(test_file.isOpen(), true)
	TEST_EQUAL(test_file.getOpenMode(), File::IN)
	test_file.close();
	TEST_EQUAL(test_file.isOpen(), false)

	DCDFile test_file2("test.out.dcd", File::OUT);
	TEST_EQUAL(test_file2.isOpen(), true)
	TEST_EQUAL(test_file2.getOpenMode(), File::OUT)
	test_file2.close();
	TEST_EQUAL(test_file2.isOpen(), false)
RESULT

CHECK(DCDFile::DCDFile& operator = (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
	DCDFile two;
	two = one;
	bool test = (one == two);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::clear() throw())
	DCDFile file(dcd_test_file, File::IN);
	file.clear();
	DCDFile empty;
	bool test = (file == empty);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::bool operator == (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
  DCDFile two(dcd_test_file, File::IN);
	bool test = (one == two);
	TEST_EQUAL(test, true)
	DCDFile three;
	test = (one == three);
	TEST_EQUAL(test, false)
RESULT

CHECK(DCDFile::init() throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::readHeader() throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::writeHeader() throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::append(const SnapShot& snapshot) throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::read(SnapShot& snapshot) throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::flushToDisk(const ::std::vector<SnapShot> buffer) throw())
  //BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>#pragma once

#include "function_trid.hpp"
#include "function_beale.hpp"
#include "function_booth.hpp"
#include "function_cauchy.hpp"
#include "function_sphere.hpp"
#include "function_matyas.hpp"
#include "function_powell.hpp"
#include "function_colville.hpp"
#include "function_zakharov.hpp"
#include "function_mccormick.hpp"
#include "function_himmelblau.hpp"
#include "function_rosenbrock.hpp"
#include "function_3hump_camel.hpp"
#include "function_sum_squares.hpp"
#include "function_dixon_price.hpp"
#include "function_bohachevsky.hpp"
#include "function_goldstein_price.hpp"
#include "function_styblinski_tang.hpp"
#include "function_rotated_ellipsoid.hpp"

namespace nano
{
        enum class test_type
        {
                easy,           ///< easy test functions even for GD  (e.g. convex) - mostly useful for unit testing
                all
        };

        ///
        /// \brief run the given operator for each test function having the number of dimensions within the given range
        ///
        template
        <
                typename tscalar,
                test_type type,
                typename toperator
        >
        void foreach_test_function(
                const typename problem_t<tscalar>::tsize& min_dims,
                const typename problem_t<tscalar>::tsize& max_dims,
                const toperator& op)
        {
                switch (type)
                {
                case test_type::all:
                        op(function_beale_t<tscalar>());
                        op(function_booth_t<tscalar>());
                        op(function_matyas_t<tscalar>());
                        op(function_colville_t<tscalar>());
                        op(function_mccormick_t<tscalar>());
                        op(function_rosenbrock_t<tscalar>(2));
                        op(function_rosenbrock_t<tscalar>(3));
                        op(function_3hump_camel_t<tscalar>());
                        op(function_goldstein_price_t<tscalar>());
                        op(function_himmelblau_t<tscalar>());
                        op(function_bohachevsky_t<tscalar>(btype::one));
                        op(function_bohachevsky_t<tscalar>(btype::two));
                        op(function_bohachevsky_t<tscalar>(btype::three));
                        break;

                default:
                        break;
                }

                for (typename nano::problem_t<tscalar>::tsize dims = min_dims; dims <= max_dims; dims *= 2)
                {
                        switch (type)
                        {
                        case test_type::all:
                                op(function_trid_t<tscalar>(dims));
                                op(function_powell_t<tscalar>(dims));
                                op(function_zakharov_t<tscalar>(dims));
                                op(function_dixon_price_t<tscalar>(dims));
                                op(function_styblinski_tang_t<tscalar>(dims));
                                // NB: fallthrough!

                        case test_type::easy:
                        default:

                                op(function_cauchy_t<tscalar>(dims));
                                op(function_sphere_t<tscalar>(dims));
                                op(function_sum_squares_t<tscalar>(dims));
                                op(function_rotated_ellipsoid_t<tscalar>(dims));
                                break;
                        }
                }
        }
}
<commit_msg>skip low-dimensional test functions if min-dims changed<commit_after>#pragma once

#include "function_trid.hpp"
#include "function_beale.hpp"
#include "function_booth.hpp"
#include "function_cauchy.hpp"
#include "function_sphere.hpp"
#include "function_matyas.hpp"
#include "function_powell.hpp"
#include "function_colville.hpp"
#include "function_zakharov.hpp"
#include "function_mccormick.hpp"
#include "function_himmelblau.hpp"
#include "function_rosenbrock.hpp"
#include "function_3hump_camel.hpp"
#include "function_sum_squares.hpp"
#include "function_dixon_price.hpp"
#include "function_bohachevsky.hpp"
#include "function_goldstein_price.hpp"
#include "function_styblinski_tang.hpp"
#include "function_rotated_ellipsoid.hpp"

namespace nano
{
        enum class test_type
        {
                easy,           ///< easy test functions even for GD  (e.g. convex) - mostly useful for unit testing
                all
        };

        ///
        /// \brief run the given operator for each test function having the number of dimensions within the given range
        ///
        template
        <
                typename tscalar,
                test_type type,
                typename toperator
        >
        void foreach_test_function(
                const typename problem_t<tscalar>::tsize& min_dims,
                const typename problem_t<tscalar>::tsize& max_dims,
                const toperator& op)
        {
                if (min_dims == 1)
                {
                        switch (type)
                        {
                        case test_type::all:
                                op(function_beale_t<tscalar>());
                                op(function_booth_t<tscalar>());
                                op(function_matyas_t<tscalar>());
                                op(function_colville_t<tscalar>());
                                op(function_mccormick_t<tscalar>());
                                op(function_rosenbrock_t<tscalar>(2));
                                op(function_rosenbrock_t<tscalar>(3));
                                op(function_3hump_camel_t<tscalar>());
                                op(function_goldstein_price_t<tscalar>());
                                op(function_himmelblau_t<tscalar>());
                                op(function_bohachevsky_t<tscalar>(btype::one));
                                op(function_bohachevsky_t<tscalar>(btype::two));
                                op(function_bohachevsky_t<tscalar>(btype::three));
                                break;

                        default:
                                break;
                        }
                }

                for (typename nano::problem_t<tscalar>::tsize dims = min_dims; dims <= max_dims; dims *= 2)
                {
                        switch (type)
                        {
                        case test_type::all:
                                op(function_trid_t<tscalar>(dims));
                                op(function_powell_t<tscalar>(dims));
                                op(function_zakharov_t<tscalar>(dims));
                                op(function_dixon_price_t<tscalar>(dims));
                                op(function_styblinski_tang_t<tscalar>(dims));
                                // NB: fallthrough!

                        case test_type::easy:
                        default:

                                op(function_cauchy_t<tscalar>(dims));
                                op(function_sphere_t<tscalar>(dims));
                                op(function_sum_squares_t<tscalar>(dims));
                                op(function_rotated_ellipsoid_t<tscalar>(dims));
                                break;
                        }
                }
        }
}
<|endoftext|>


<commit_before>#include "GeometryShader.h"
#include "Director.h"

using namespace Rendering::Shader;

GeometryShader::GeometryShader(ID3DBlob* blob, const std::string& key)
	: ShaderForm(blob, key), _shader(nullptr)
{
	_type = Type::Geometry;
}

GeometryShader::~GeometryShader()
{
	SAFE_RELEASE(_shader);
}

bool GeometryShader::Create(ID3D11Device* device)
{
	if(_blob == nullptr)
		return false;

	HRESULT hr = device->CreateGeometryShader(_blob->GetBufferPointer(), _blob->GetBufferSize(), nullptr, &_shader);

	if( FAILED(hr) )
		return false;

	return true;
}

void GeometryShader::BindShaderToContext(ID3D11DeviceContext* context)
{
	context->GSSetShader(_shader, nullptr, 0);
}

void GeometryShader::BindResourcesToContext(ID3D11DeviceContext* context,
								   const std::vector<InputConstBuffer>* constBuffers,
								   const std::vector<InputTexture>* textures,
								   const std::vector<InputShaderResourceBuffer>* srBuffers)
{
	if(constBuffers)
	{
		for(auto iter = constBuffers->begin(); iter != constBuffers->end(); ++iter)
		{
			ID3D11Buffer* buffer = (*iter).buffer->GetBuffer();
			if(buffer && iter->useGS)
				context->GSSetConstantBuffers( (*iter).bindIndex, 1, &buffer );
		}
	}

	if(textures)
	{
		for(auto iter = textures->begin(); iter != textures->end(); ++iter)
		{
			auto srv = iter->texture->GetShaderResourceView()->GetView();
			if(srv && iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &srv );
		}
	}

	if(srBuffers)
	{
		for(auto iter = srBuffers->begin(); iter != srBuffers->end(); ++iter)
		{
			auto srv = iter->srBuffer->GetShaderResourceView();
			if(srv && iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, srv );
		}
	}
}

void GeometryShader::Clear(ID3D11DeviceContext* context,
						   const std::vector<InputConstBuffer>* constBuffers,
						   const std::vector<InputTexture>* textures,
						   const std::vector<InputShaderResourceBuffer>* srBuffers)
{
	if(textures)
	{
		ID3D11ShaderResourceView* nullSrv = nullptr;

		for(auto iter = textures->begin(); iter != textures->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &nullSrv );
		}
	}

	if(srBuffers)
	{
		ID3D11ShaderResourceView* nullSrv = nullptr;

		for(auto iter = srBuffers->begin(); iter != srBuffers->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &nullSrv );
		}
	}

	if(constBuffers)
	{
		ID3D11Buffer* nullBuffer = nullptr;

		for(auto iter = constBuffers->begin(); iter != constBuffers->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetConstantBuffers( iter->bindIndex, 1, &nullBuffer );
		}
	}
}<commit_msg>GeometryShader.cpp - Bind 추가 #32<commit_after>#include "GeometryShader.h"
#include "Director.h"

using namespace Rendering::Shader;

GeometryShader::GeometryShader(ID3DBlob* blob, const std::string& key)
	: ShaderForm(blob, key), _shader(nullptr)
{
	_type = Type::Geometry;
}

GeometryShader::~GeometryShader()
{
	SAFE_RELEASE(_shader);
}

bool GeometryShader::Create(ID3D11Device* device)
{
	if(_blob == nullptr)
		return false;

	HRESULT hr = device->CreateGeometryShader(_blob->GetBufferPointer(), _blob->GetBufferSize(), nullptr, &_shader);

	if( FAILED(hr) )
		return false;

	return true;
}

void GeometryShader::BindShaderToContext(ID3D11DeviceContext* context)
{
	context->GSSetShader(_shader, nullptr, 0);
}

void GeometryShader::BindResourcesToContext(ID3D11DeviceContext* context,
								   const std::vector<InputConstBuffer>* constBuffers,
								   const std::vector<InputTexture>* textures,
								   const std::vector<InputShaderResourceBuffer>* srBuffers)
{
	if(constBuffers)
	{
		for(auto iter = constBuffers->begin(); iter != constBuffers->end(); ++iter)
		{
			ID3D11Buffer* buffer = (*iter).buffer->GetBuffer();
			if(buffer && iter->useGS)
				context->GSSetConstantBuffers( (*iter).bindIndex, 1, &buffer );
		}
	}

	if(textures)
	{
		for(auto iter = textures->begin(); iter != textures->end(); ++iter)
		{
			auto srv = iter->texture->GetShaderResourceView()->GetView();
			if(srv && iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &srv );
		}
	}

	if(srBuffers)
	{
		for(auto iter = srBuffers->begin(); iter != srBuffers->end(); ++iter)
		{
			auto srv = iter->srBuffer->GetShaderResourceView();
			if(srv && iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, srv );
		}
	}
}

void GeometryShader::Clear(ID3D11DeviceContext* context,
						   const std::vector<InputConstBuffer>* constBuffers,
						   const std::vector<InputTexture>* textures,
						   const std::vector<InputShaderResourceBuffer>* srBuffers)
{
	if(textures)
	{
		ID3D11ShaderResourceView* nullSrv = nullptr;

		for(auto iter = textures->begin(); iter != textures->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &nullSrv );
		}
	}

	if(srBuffers)
	{
		ID3D11ShaderResourceView* nullSrv = nullptr;

		for(auto iter = srBuffers->begin(); iter != srBuffers->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetShaderResources( iter->bindIndex, 1, &nullSrv );
		}
	}

	if(constBuffers)
	{
		ID3D11Buffer* nullBuffer = nullptr;

		for(auto iter = constBuffers->begin(); iter != constBuffers->end(); ++iter)
		{
			if(iter->useGS)
				context->GSSetConstantBuffers( iter->bindIndex, 1, &nullBuffer );
		}
	}
}

void GeometryShader::BindTexture(ID3D11DeviceContext* context, TextureBindIndex bind, const Texture::Texture2D* tex)
{
	ID3D11ShaderResourceView* srv = tex ? tex->GetShaderResourceView()->GetView() : nullptr;
	context->GSSetShaderResources(uint(bind), 1, &srv);
}

void GeometryShader::BindSamplerState(ID3D11DeviceContext* context, SamplerStateBindIndex bind, ID3D11SamplerState* samplerState)
{
	context->GSSetSamplers(uint(bind), 1, &samplerState);
}

void GeometryShader::BindConstBuffer(ID3D11DeviceContext* context, ConstBufferBindIndex bind, const Buffer::ConstBuffer* cb)
{
	ID3D11Buffer* buf = cb ? cb->GetBuffer() : nullptr;
	context->GSSetConstantBuffers(uint(bind), 1, &buf);
}

void GeometryShader::BindShaderResourceBuffer(ID3D11DeviceContext* context, TextureBindIndex bind, const Buffer::ShaderResourceBuffer* srBuffer)
{
	ID3D11ShaderResourceView* srv = srBuffer ? srBuffer->GetShaderResourceView() : nullptr;
	context->GSSetShaderResources(uint(bind), 1, &srv);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "messagedock.h"

#include <core/gluon_global.h>
#include <engine/game.h>

#include <KDE/KLocalizedString>
#include <KDE/KToolBar>
#include <KDE/KAction>

// Yup, this should be a view... but for now...
#include <QtGui/QListWidget>
#include <QtGui/QVBoxLayout>
#include <QtGui/QApplication>
#include <QtGui/QClipboard>

using namespace GluonCreator;

class MessageDock::MessageDockPrivate
{
    public:
        MessageDockPrivate()
        {
            view = 0;
        }
        QListWidget* view;
};

MessageDock::MessageDock( const QString& title, QWidget* parent, Qt::WindowFlags flags )
    : QDockWidget( title, parent, flags ),
      d( new MessageDockPrivate )
{
    setObjectName( "MessageDock" );

    d->view = new QListWidget( this );
    d->view->addItem( new QListWidgetItem( i18n( "Welcome to Gluon Creator %1" ).arg( GluonCore::Global::versionString() ), d->view ) );

    connect( GluonEngine::Game::instance(), SIGNAL( showDebug( const QString& ) ), SLOT( showDebug( const QString& ) ) );

    QWidget* widget = new QWidget( this );
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins( 0, 0, 0, 0 );
    layout->setSpacing( 0 );
    widget->setLayout( layout );

    KToolBar* toolBar = new KToolBar(this);
    toolBar->setIconDimensions(16);

    QAction* selectAll = toolBar->addAction(KIcon("edit-select-all"), i18n("Select All"), this, SLOT( selectAll() ) );
    d->view->addAction( selectAll );

    QAction* copy = toolBar->addAction(KIcon("edit-copy"), i18n("Copy"), this, SLOT( copy() ) );
    d->view->addAction( copy );

    KAction* separator = new KAction( d->view );
    separator->setSeparator( true );
    d->view->addAction( separator );

    QAction* clearSelection = toolBar->addAction(KIcon("edit-clear-list"), i18n("Clear Selection"), this, SLOT( clearSelection() ) );
    d->view->addAction( clearSelection );

    layout->addWidget(toolBar);
    layout->addWidget(d->view);
    setWidget(widget);
}

void MessageDock::showDebug( const QString& debugText )
{
    QListWidgetItem* item = new QListWidgetItem( debugText, d->view );
    d->view->addItem( item );
    d->view->scrollToItem( item );
}

MessageDock::~MessageDock()
{
    delete d;
}

void MessageDock::copy()
{
    QStringList messages;
    foreach( QListWidgetItem* item, d->view->selectedItems())
        messages << item->text();

    QApplication::clipboard()->setText(messages.join("\n"));
}

void MessageDock::selectAll()
{
    int itemsCount = d->view->count();
    for (int i = 0; i < itemsCount; ++i)
        d->view->item(i)->setSelected(true);
}

void MessageDock::clearSelection()
{
    int itemsCount = d->view->count();
    for (int i = 0; i < itemsCount; ++i)
        d->view->item(i)->setSelected(false);
}
<commit_msg>Creator: Set the selection mode for extended from the default Single<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "messagedock.h"

#include <core/gluon_global.h>
#include <engine/game.h>

#include <KDE/KLocalizedString>
#include <KDE/KToolBar>
#include <KDE/KAction>

// Yup, this should be a view... but for now...
#include <QtGui/QListWidget>
#include <QtGui/QVBoxLayout>
#include <QtGui/QApplication>
#include <QtGui/QClipboard>

using namespace GluonCreator;

class MessageDock::MessageDockPrivate
{
    public:
        MessageDockPrivate()
        {
            view = 0;
        }
        QListWidget* view;
};

MessageDock::MessageDock( const QString& title, QWidget* parent, Qt::WindowFlags flags )
    : QDockWidget( title, parent, flags ),
      d( new MessageDockPrivate )
{
    setObjectName( "MessageDock" );

    d->view = new QListWidget( this );
    d->view->addItem( new QListWidgetItem( i18n( "Welcome to Gluon Creator %1" ).arg( GluonCore::Global::versionString() ), d->view ) );
    d->view->setSelectionMode( QAbstractItemView::ExtendedSelection );

    connect( GluonEngine::Game::instance(), SIGNAL( showDebug( const QString& ) ), SLOT( showDebug( const QString& ) ) );

    QWidget* widget = new QWidget( this );
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins( 0, 0, 0, 0 );
    layout->setSpacing( 0 );
    widget->setLayout( layout );

    KToolBar* toolBar = new KToolBar(this);
    toolBar->setIconDimensions(16);

    QAction* selectAll = toolBar->addAction(KIcon("edit-select-all"), i18n("Select All"), this, SLOT( selectAll() ) );
    d->view->addAction( selectAll );

    QAction* copy = toolBar->addAction(KIcon("edit-copy"), i18n("Copy"), this, SLOT( copy() ) );
    d->view->addAction( copy );

    KAction* separator = new KAction( d->view );
    separator->setSeparator( true );
    d->view->addAction( separator );

    QAction* clearSelection = toolBar->addAction(KIcon("edit-clear-list"), i18n("Clear Selection"), this, SLOT( clearSelection() ) );
    d->view->addAction( clearSelection );

    layout->addWidget(toolBar);
    layout->addWidget(d->view);
    setWidget(widget);
}

void MessageDock::showDebug( const QString& debugText )
{
    QListWidgetItem* item = new QListWidgetItem( debugText, d->view );
    d->view->addItem( item );
    d->view->scrollToItem( item );
}

MessageDock::~MessageDock()
{
    delete d;
}

void MessageDock::copy()
{
    QStringList messages;
    foreach( QListWidgetItem* item, d->view->selectedItems())
        messages << item->text();

    QApplication::clipboard()->setText(messages.join("\n"));
}

void MessageDock::selectAll()
{
    int itemsCount = d->view->count();
    for (int i = 0; i < itemsCount; ++i)
        d->view->item(i)->setSelected(true);
}

void MessageDock::clearSelection()
{
    int itemsCount = d->view->count();
    for (int i = 0; i < itemsCount; ++i)
        d->view->item(i)->setSelected(false);
}
<|endoftext|>


<commit_before><commit_msg>Disable a failing test on linux.<commit_after><|endoftext|>


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

/***************************************************************************
 * Renders a vertically split GL_TEXTURE_EXTERNAL_OES texture.
 ***************************************************************************/

#include "oes_vertical_stereo_shader.h"

#include "gl/gl_program.h"
#include "objects/material.h"
#include "objects/mesh.h"
#include "objects/components/render_data.h"
#include "objects/textures/texture.h"
#include "util/gvr_gl.h"
#include "engine/renderer/renderer.h"

namespace gvr {
static const char VERTEX_SHADER[] = "attribute vec4 a_position;\n"
        "attribute vec4 a_tex_coord;\n"
        "uniform mat4 u_mvp;\n"
        "varying vec2 v_tex_coord;\n"
        "void main() {\n"
        "  v_tex_coord = a_tex_coord.xy;\n"
        "  gl_Position = u_mvp * a_position;\n"
        "}\n";

static const char FRAGMENT_SHADER[] =
        "#extension GL_OES_EGL_image_external : require\n"
                "precision highp float;\n"
                "uniform samplerExternalOES u_texture;\n"
                "uniform vec3 u_color;\n"
                "uniform float u_opacity;\n"
                "uniform int u_right;\n"
                "varying vec2 v_tex_coord;\n"
                "void main()\n"
                "{\n"
                "  vec2 tex_coord = vec2(v_tex_coord.x, 0.5 * (v_tex_coord.y + float(u_right)));\n"
                "  vec4 color = texture2D(u_texture, tex_coord);\n"
                "  gl_FragColor = vec4(color.r * u_color.r * u_opacity, color.g * u_color.g * u_opacity, color.b * u_color.b * u_opacity, color.a * u_opacity);\n"
                "}\n";

OESVerticalStereoShader::OESVerticalStereoShader() :
        u_mvp_(0), u_texture_(0), u_color_(
                0), u_opacity_(0), u_right_(0) {
    program_ = new GLProgram(VERTEX_SHADER, FRAGMENT_SHADER);
    u_mvp_ = glGetUniformLocation(program_->id(), "u_mvp");
    u_texture_ = glGetUniformLocation(program_->id(), "u_texture");
    u_color_ = glGetUniformLocation(program_->id(), "u_color");
    u_opacity_ = glGetUniformLocation(program_->id(), "u_opacity");
    u_right_ = glGetUniformLocation(program_->id(), "u_right");
}

OESVerticalStereoShader::~OESVerticalStereoShader() {
    delete program_;
}

void OESVerticalStereoShader::render(RenderState* rstate,
        RenderData* render_data, Material* material) {
    Mesh* mesh = render_data->mesh();
    Texture* texture = material->getTexture("main_texture");
    glm::vec3 color = material->getVec3("color");
    float opacity = material->getFloat("opacity");
    bool mono_rendering;

    if (texture->getTarget() != GL_TEXTURE_EXTERNAL_OES) {
        std::string error =
                "OESVerticalStereoShader::render : texture with wrong target";
        throw error;
    }

    try {
        mono_rendering = material->getFloat("mono_rendering") == 1;
    } catch (std::string& error) {
        mono_rendering = false;
    }

    mesh->generateVAO();

    glUseProgram(program_->id());

    glUniformMatrix4fv(u_mvp_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mvp));
    glActiveTexture (GL_TEXTURE0);
    glBindTexture(texture->getTarget(), texture->getId());
    glUniform1i(u_texture_, 0);
    glUniform3f(u_color_, color.r, color.g, color.b);
    glUniform1f(u_opacity_, opacity);
    glUniform1i(u_right_, mono_rendering || rstate->uniforms.u_right ? 1 : 0);

    glDrawElements(render_data->draw_mode(), mesh->indices().size(), GL_UNSIGNED_SHORT,
            0);
    glBindVertexArray(0);

    checkGlError("OESVerticalStereoShader::render");
}

}
<commit_msg>Fixed crash in OESHorizontalStereoShader The shader was not binding the vertex array<commit_after>/* Copyright 2015 Samsung Electronics Co., LTD
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/***************************************************************************
 * Renders a vertically split GL_TEXTURE_EXTERNAL_OES texture.
 ***************************************************************************/

#include "oes_vertical_stereo_shader.h"

#include "gl/gl_program.h"
#include "objects/material.h"
#include "objects/mesh.h"
#include "objects/components/render_data.h"
#include "objects/textures/texture.h"
#include "util/gvr_gl.h"
#include "engine/renderer/renderer.h"

namespace gvr {
static const char VERTEX_SHADER[] = "attribute vec4 a_position;\n"
        "attribute vec4 a_tex_coord;\n"
        "uniform mat4 u_mvp;\n"
        "varying vec2 v_tex_coord;\n"
        "void main() {\n"
        "  v_tex_coord = a_tex_coord.xy;\n"
        "  gl_Position = u_mvp * a_position;\n"
        "}\n";

static const char FRAGMENT_SHADER[] =
        "#extension GL_OES_EGL_image_external : require\n"
                "precision highp float;\n"
                "uniform samplerExternalOES u_texture;\n"
                "uniform vec3 u_color;\n"
                "uniform float u_opacity;\n"
                "uniform int u_right;\n"
                "varying vec2 v_tex_coord;\n"
                "void main()\n"
                "{\n"
                "  vec2 tex_coord = vec2(v_tex_coord.x, 0.5 * (v_tex_coord.y + float(u_right)));\n"
                "  vec4 color = texture2D(u_texture, tex_coord);\n"
                "  gl_FragColor = vec4(color.r * u_color.r * u_opacity, color.g * u_color.g * u_opacity, color.b * u_color.b * u_opacity, color.a * u_opacity);\n"
                "}\n";

OESVerticalStereoShader::OESVerticalStereoShader() :
        u_mvp_(0), u_texture_(0), u_color_(
                0), u_opacity_(0), u_right_(0) {
    program_ = new GLProgram(VERTEX_SHADER, FRAGMENT_SHADER);
    u_mvp_ = glGetUniformLocation(program_->id(), "u_mvp");
    u_texture_ = glGetUniformLocation(program_->id(), "u_texture");
    u_color_ = glGetUniformLocation(program_->id(), "u_color");
    u_opacity_ = glGetUniformLocation(program_->id(), "u_opacity");
    u_right_ = glGetUniformLocation(program_->id(), "u_right");
}

OESVerticalStereoShader::~OESVerticalStereoShader() {
    delete program_;
}

void OESVerticalStereoShader::render(RenderState* rstate,
        RenderData* render_data, Material* material) {
    Mesh* mesh = render_data->mesh();
    Texture* texture = material->getTexture("main_texture");
    glm::vec3 color = material->getVec3("color");
    float opacity = material->getFloat("opacity");
    bool mono_rendering;

    if (texture->getTarget() != GL_TEXTURE_EXTERNAL_OES) {
        std::string error =
                "OESVerticalStereoShader::render : texture with wrong target";
        throw error;
    }

    try {
        mono_rendering = material->getFloat("mono_rendering") == 1;
    } catch (std::string& error) {
        mono_rendering = false;
    }

    mesh->generateVAO();

    glUseProgram(program_->id());

    glUniformMatrix4fv(u_mvp_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mvp));
    glActiveTexture (GL_TEXTURE0);
    glBindTexture(texture->getTarget(), texture->getId());
    glUniform1i(u_texture_, 0);
    glUniform3f(u_color_, color.r, color.g, color.b);
    glUniform1f(u_opacity_, opacity);
    glUniform1i(u_right_, mono_rendering || rstate->uniforms.u_right ? 1 : 0);
    glBindVertexArray(mesh->getVAOId());

    glDrawElements(render_data->draw_mode(), mesh->indices().size(), GL_UNSIGNED_SHORT,
            0);
    glBindVertexArray(0);

    checkGlError("OESVerticalStereoShader::render");
}

}
<|endoftext|>


<commit_before>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=========================================================================*/

// Qt includes
#include <QDebug>
#include <QScrollBar>
#include <QTextBlock>
#include <QAbstractTextDocumentLayout>

// CTK includes
#include "ctkFittedTextBrowser.h"
#include "ctkFittedTextBrowser_p.h"

static const char moreAnchor[] = "show_details";
static const char lessAnchor[] = "hide_details";

//-----------------------------------------------------------------------------
ctkFittedTextBrowserPrivate::ctkFittedTextBrowserPrivate(ctkFittedTextBrowser& object)
  :q_ptr(&object)
{
  this->Collapsed = true;
  this->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Text;
  this->ShowDetailsText = object.tr("Show details...");
  this->HideDetailsText = object.tr("Hide details.");
  QString HideDetailsText;
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowserPrivate::~ctkFittedTextBrowserPrivate()
{
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowserPrivate::updateCollapsedText()
{
  Q_Q(ctkFittedTextBrowser);
  bool html = (this->CollapsibleTextSetter == ctkFittedTextBrowserPrivate::Html || this->CollapsibleText.indexOf("") >= 0);
  if (html)
  {
    q->setHtml(this->collapsedTextFromHtml());
  }
  else
  {
    q->setHtml(this->collapsedTextFromPlainText());
  }
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapsedTextFromPlainText() const
{
  Q_Q(const ctkFittedTextBrowser);
  int teaserEndPosition = this->CollapsibleText.indexOf("\n");
  if (teaserEndPosition < 0)
  {
    return this->CollapsibleText;
  }
  QString finalText;
  finalText.append("");
  finalText.append(this->Collapsed ? this->CollapsibleText.left(teaserEndPosition) : this->CollapsibleText);
  finalText.append(this->collapseLinkText());
  finalText.append("");
  // Remove line break to allow continuation of line.
  finalText.replace(finalText.indexOf('\n'), 1, ' ');
  // In plain text line breaks were indicated by newline, but we now use html,
  // so line breaks must use

  finalText.replace("\n", "
");
  return finalText;
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapsedTextFromHtml() const
{
  Q_Q(const ctkFittedTextBrowser);
  const QString lineBreak("
");
  int teaserEndPosition = this->CollapsibleText.indexOf(lineBreak);
  if (teaserEndPosition < 0)
  {
    return this->CollapsibleText;
  }

  QString finalText = this->CollapsibleText;
  if (this->Collapsed)
  {
    finalText = finalText.left(teaserEndPosition) + this->collapseLinkText();
    // By truncating the full text we might have deleted the closing  tag
    // restore it now.
    if (finalText.contains("<html") && !finalText.contains("</html"))
    {
      finalText.append("");
    }
  }
  else
  {
    // Remove
 to allow continuation of line and avoid extra space
    // when
 element is used as well.
    finalText.replace(finalText.indexOf(lineBreak), lineBreak.size(), " ");
    // Add link text before closing  or  tag
    if (finalText.contains(""))
    {
      finalText.replace("", this->collapseLinkText() + "");
    }
    else if (finalText.contains(""))
    {
      finalText.replace("", this->collapseLinkText() + "");
    }
    else
    {
      finalText.append(this->collapseLinkText());
    }
  }
  return finalText;
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapseLinkText() const
{
  Q_Q(const ctkFittedTextBrowser);
  if (this->Collapsed)
  {
    return QString(" " + this->ShowDetailsText + "";
  }
  else
  {
    return QString(" " + this->HideDetailsText + "";
  }
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowser::ctkFittedTextBrowser(QWidget* _parent)
  : QTextBrowser(_parent)
  , d_ptr(new ctkFittedTextBrowserPrivate(*this))
{
  this->connect(this, SIGNAL(textChanged()), SLOT(heightForWidthMayHaveChanged()));
  QSizePolicy newSizePolicy = QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
  this->setSizePolicy(newSizePolicy);
  this->connect(this, SIGNAL(anchorClicked(QUrl)), SLOT(anchorClicked(QUrl)));
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowser::~ctkFittedTextBrowser()
{

}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::heightForWidthMayHaveChanged()
{
  this->updateGeometry();
}

//-----------------------------------------------------------------------------
int ctkFittedTextBrowser::heightForWidth(int _width) const
{
  QTextDocument* doc = this->document();
  qreal savedWidth = doc->textWidth();

  // Fudge factor. This is the difference between the frame and the
  // viewport.
  int fudge = 2 * this->frameWidth();

  int horizontalScrollbarHeight = 0;
  if (this->horizontalScrollBar()->isVisible())
  {
    horizontalScrollbarHeight = this->horizontalScrollBar()->height() + fudge;
  }

  // Do the calculation assuming no scrollbars
  doc->setTextWidth(_width - fudge);
  int noScrollbarHeight =
    doc->documentLayout()->documentSize().height() + fudge;

  // (If noScrollbarHeight is greater than the maximum height we'll be
  // allowed, then there will be scrollbars, and the actual required
  // height will be even higher. But since in this case we've already
  // hit the maximum height, it doesn't matter that we underestimate.)

  // Get minimum height (even if string is empty): one line of text
  int _minimumHeight = QFontMetrics(doc->defaultFont()).lineSpacing() + fudge;
  int ret = qMax(noScrollbarHeight, _minimumHeight) + horizontalScrollbarHeight;

  doc->setTextWidth(savedWidth);
  return ret;
}

//-----------------------------------------------------------------------------
QSize ctkFittedTextBrowser::minimumSizeHint() const {
  QSize s(this->size().width(), 0);
  if (s.width() == 0)
    {
    //s.setWidth(400); // arbitrary value
    return QTextBrowser::minimumSizeHint();
    }
  s.setHeight(this->heightForWidth(s.width()));
  return s;
}

//-----------------------------------------------------------------------------
QSize ctkFittedTextBrowser::sizeHint() const {
  return this->minimumSizeHint();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::resizeEvent(QResizeEvent* e)
{
  this->QTextBrowser::resizeEvent(e);
  if (e->size().height() != this->heightForWidth(e->size().width()))
    {
    this->heightForWidthMayHaveChanged();
    }
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsibleText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Text;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::collapsibleText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->CollapsibleText;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsiblePlainText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::PlainText;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsibleHtml(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Html;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::anchorClicked(const QUrl &url)
{
  Q_D(ctkFittedTextBrowser);
  if (url.path().isEmpty())
  {
    if (url.fragment() == moreAnchor)
    {
      this->setCollapsed(false);
    }
    else if (url.fragment() == lessAnchor)
    {
      this->setCollapsed(true);
    }
  }
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsed(bool collapsed)
{
  Q_D(ctkFittedTextBrowser);
  if (d->Collapsed == collapsed)
  {
    // no change
    return;
  }
  d->Collapsed = collapsed;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
bool ctkFittedTextBrowser::collapsed() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->Collapsed;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setShowDetailsText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  if (d->ShowDetailsText == text)
  {
    // no change
    return;
  }
  d->ShowDetailsText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::showDetailsText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->ShowDetailsText;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setHideDetailsText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  if (d->HideDetailsText == text)
  {
    // no change
    return;
  }
  d->HideDetailsText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::hideDetailsText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->HideDetailsText;
}
<commit_msg>ENH: Improve ctkFittedTextBrowser collapsed text formatting<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=========================================================================*/

// Qt includes
#include <QDebug>
#include <QScrollBar>
#include <QTextBlock>
#include <QAbstractTextDocumentLayout>

// CTK includes
#include "ctkFittedTextBrowser.h"
#include "ctkFittedTextBrowser_p.h"

static const char moreAnchor[] = "show_details";
static const char lessAnchor[] = "hide_details";

//-----------------------------------------------------------------------------
ctkFittedTextBrowserPrivate::ctkFittedTextBrowserPrivate(ctkFittedTextBrowser& object)
  :q_ptr(&object)
{
  this->Collapsed = true;
  this->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Text;
  this->ShowDetailsText = object.tr("Show details...");
  this->HideDetailsText = object.tr("Hide details.");
  QString HideDetailsText;
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowserPrivate::~ctkFittedTextBrowserPrivate()
{
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowserPrivate::updateCollapsedText()
{
  Q_Q(ctkFittedTextBrowser);
  bool html = (this->CollapsibleTextSetter == ctkFittedTextBrowserPrivate::Html || this->CollapsibleText.indexOf("") >= 0);
  if (html)
  {
    q->setHtml(this->collapsedTextFromHtml());
  }
  else
  {
    q->setHtml(this->collapsedTextFromPlainText());
  }
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapsedTextFromPlainText() const
{
  Q_Q(const ctkFittedTextBrowser);
  int teaserEndPosition = this->CollapsibleText.indexOf("\n");
  if (teaserEndPosition < 0)
  {
    return this->CollapsibleText;
  }
  QString finalText;
  finalText.append("");
  finalText.append(this->Collapsed ? this->CollapsibleText.left(teaserEndPosition) : this->CollapsibleText);
  finalText.append(this->collapseLinkText());
  finalText.append("");
  // Remove line break to allow continuation of line.
  finalText.replace(finalText.indexOf('\n'), 1, "");
  // In plain text line breaks were indicated by newline, but we now use html,
  // so line breaks must use

  finalText.replace("\n", "
");
  return finalText;
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapsedTextFromHtml() const
{
  Q_Q(const ctkFittedTextBrowser);
  const QString lineBreak("
");
  int teaserEndPosition = this->CollapsibleText.indexOf(lineBreak);
  if (teaserEndPosition < 0)
  {
    return this->CollapsibleText;
  }

  QString finalText = this->CollapsibleText;
  if (this->Collapsed)
  {
    finalText = finalText.left(teaserEndPosition) + this->collapseLinkText();
    // By truncating the full text we might have deleted the closing  tag
    // restore it now.
    if (finalText.contains("<html") && !finalText.contains("</html"))
    {
      finalText.append("");
    }
  }
  else
  {
    // Remove
 to allow continuation of line and avoid extra space
    // when
 element is used as well.
    finalText.replace(finalText.indexOf(lineBreak), lineBreak.size(), "");
    // Add link text before closing  or  tag
    if (finalText.contains(""))
    {
      finalText.replace("", this->collapseLinkText() + "");
    }
    else if (finalText.contains(""))
    {
      finalText.replace("", this->collapseLinkText() + "");
    }
    else
    {
      finalText.append(this->collapseLinkText());
    }
  }
  return finalText;
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowserPrivate::collapseLinkText() const
{
  Q_Q(const ctkFittedTextBrowser);
  if (this->Collapsed)
  {
    return QString("… " + this->ShowDetailsText + "";
  }
  else
  {
    return QString(" " + this->HideDetailsText + "";
  }
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowser::ctkFittedTextBrowser(QWidget* _parent)
  : QTextBrowser(_parent)
  , d_ptr(new ctkFittedTextBrowserPrivate(*this))
{
  this->connect(this, SIGNAL(textChanged()), SLOT(heightForWidthMayHaveChanged()));
  QSizePolicy newSizePolicy = QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
  this->setSizePolicy(newSizePolicy);
  this->connect(this, SIGNAL(anchorClicked(QUrl)), SLOT(anchorClicked(QUrl)));
}

//-----------------------------------------------------------------------------
ctkFittedTextBrowser::~ctkFittedTextBrowser()
{

}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::heightForWidthMayHaveChanged()
{
  this->updateGeometry();
}

//-----------------------------------------------------------------------------
int ctkFittedTextBrowser::heightForWidth(int _width) const
{
  QTextDocument* doc = this->document();
  qreal savedWidth = doc->textWidth();

  // Fudge factor. This is the difference between the frame and the
  // viewport.
  int fudge = 2 * this->frameWidth();

  int horizontalScrollbarHeight = 0;
  if (this->horizontalScrollBar()->isVisible())
  {
    horizontalScrollbarHeight = this->horizontalScrollBar()->height() + fudge;
  }

  // Do the calculation assuming no scrollbars
  doc->setTextWidth(_width - fudge);
  int noScrollbarHeight =
    doc->documentLayout()->documentSize().height() + fudge;

  // (If noScrollbarHeight is greater than the maximum height we'll be
  // allowed, then there will be scrollbars, and the actual required
  // height will be even higher. But since in this case we've already
  // hit the maximum height, it doesn't matter that we underestimate.)

  // Get minimum height (even if string is empty): one line of text
  int _minimumHeight = QFontMetrics(doc->defaultFont()).lineSpacing() + fudge;
  int ret = qMax(noScrollbarHeight, _minimumHeight) + horizontalScrollbarHeight;

  doc->setTextWidth(savedWidth);
  return ret;
}

//-----------------------------------------------------------------------------
QSize ctkFittedTextBrowser::minimumSizeHint() const {
  QSize s(this->size().width(), 0);
  if (s.width() == 0)
    {
    //s.setWidth(400); // arbitrary value
    return QTextBrowser::minimumSizeHint();
    }
  s.setHeight(this->heightForWidth(s.width()));
  return s;
}

//-----------------------------------------------------------------------------
QSize ctkFittedTextBrowser::sizeHint() const {
  return this->minimumSizeHint();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::resizeEvent(QResizeEvent* e)
{
  this->QTextBrowser::resizeEvent(e);
  if (e->size().height() != this->heightForWidth(e->size().width()))
    {
    this->heightForWidthMayHaveChanged();
    }
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsibleText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Text;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::collapsibleText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->CollapsibleText;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsiblePlainText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::PlainText;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsibleHtml(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  d->CollapsibleTextSetter = ctkFittedTextBrowserPrivate::Html;
  d->CollapsibleText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::anchorClicked(const QUrl &url)
{
  Q_D(ctkFittedTextBrowser);
  if (url.path().isEmpty())
  {
    if (url.fragment() == moreAnchor)
    {
      this->setCollapsed(false);
    }
    else if (url.fragment() == lessAnchor)
    {
      this->setCollapsed(true);
    }
  }
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setCollapsed(bool collapsed)
{
  Q_D(ctkFittedTextBrowser);
  if (d->Collapsed == collapsed)
  {
    // no change
    return;
  }
  d->Collapsed = collapsed;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
bool ctkFittedTextBrowser::collapsed() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->Collapsed;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setShowDetailsText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  if (d->ShowDetailsText == text)
  {
    // no change
    return;
  }
  d->ShowDetailsText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::showDetailsText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->ShowDetailsText;
}

//-----------------------------------------------------------------------------
void ctkFittedTextBrowser::setHideDetailsText(const QString &text)
{
  Q_D(ctkFittedTextBrowser);
  if (d->HideDetailsText == text)
  {
    // no change
    return;
  }
  d->HideDetailsText = text;
  d->updateCollapsedText();
}

//-----------------------------------------------------------------------------
QString ctkFittedTextBrowser::hideDetailsText() const
{
  Q_D(const ctkFittedTextBrowser);
  return d->HideDetailsText;
}
<|endoftext|>