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

#include "riegeli/csv/csv_writer.h"

#include <stddef.h>

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

#include "absl/base/optimization.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "riegeli/base/base.h"
#include "riegeli/base/object.h"
#include "riegeli/base/status.h"
#include "riegeli/bytes/writer.h"
#include "riegeli/csv/csv_record.h"

namespace riegeli {

void CsvWriterBase::Initialize(Writer* dest, Options&& options) {
  RIEGELI_ASSERT(dest != nullptr)
      << "Failed precondition of CsvWriter: null Writer pointer";
  RIEGELI_ASSERT(options.field_separator() != options.comment())
      << "Field separator conflicts with comment character";
  if (options.quote() != absl::nullopt) {
    RIEGELI_ASSERT(*options.quote() != options.comment())
        << "Quote character conflicts with comment character";
    RIEGELI_ASSERT(*options.quote() != options.field_separator())
        << "Quote character conflicts with field separator";
  }
  if (ABSL_PREDICT_FALSE(!dest->healthy())) {
    FailWithoutAnnotation(AnnotateOverDest(dest->status()));
    return;
  }

  quotes_needed_['\n'] = true;
  quotes_needed_['\r'] = true;
  if (options.comment() != absl::nullopt) {
    quotes_needed_[static_cast<unsigned char>(*options.comment())] = true;
  }
  quotes_needed_[static_cast<unsigned char>(options.field_separator())] = true;
  if (options.quote() != absl::nullopt) {
    quotes_needed_[static_cast<unsigned char>(*options.quote())] = true;
  }
  newline_ = options.newline();
  field_separator_ = options.field_separator();
  quote_ = options.quote();

  if (options.header() != absl::nullopt) {
    has_header_ = true;
    header_ = *std::move(options.header());
    if (ABSL_PREDICT_TRUE(WriteRecord(header_.names()))) {
      --record_index_;
    }
  }
}

absl::Status CsvWriterBase::AnnotateStatusImpl(absl::Status status) {
  if (is_open()) {
    Writer& dest = *dest_writer();
    status = dest.AnnotateStatus(std::move(status));
  }
  return AnnotateOverDest(std::move(status));
}

absl::Status CsvWriterBase::AnnotateOverDest(absl::Status status) {
  if (!standalone_record_) {
    return Annotate(status, absl::StrCat("at record ", record_index()));
  }
  return status;
}

inline bool CsvWriterBase::WriteQuoted(Writer& dest, absl::string_view field,
                                       size_t already_scanned) {
  if (ABSL_PREDICT_FALSE(quote_ == absl::nullopt)) {
    return Fail(absl::InvalidArgumentError(absl::StrCat(
        "If quoting is turned off, special characters inside fields are not "
        "expressible: '",
        absl::CHexEscape(absl::string_view(&field[already_scanned], 1)), "'")));
  }
  if (ABSL_PREDICT_FALSE(!dest.WriteChar(*quote_))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  const char* start = field.data();
  const char* next_to_check = field.data() + already_scanned;
  const char* const limit = field.data() + field.size();
  // Write characters in the range [`start`..`limit`), except that if quotes are
  // found in the range [`next_to_check`..`limit`), write them twice.
  while (const char* const next_quote = static_cast<const char*>(std::memchr(
             next_to_check, *quote_, PtrDistance(next_to_check, limit)))) {
    if (ABSL_PREDICT_FALSE(
            !dest.Write(start, PtrDistance(start, next_quote + 1)))) {
      return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
    }
    start = next_quote;
    next_to_check = next_quote + 1;
  }
  if (ABSL_PREDICT_FALSE(!dest.Write(start, PtrDistance(start, limit)))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  if (ABSL_PREDICT_FALSE(!dest.WriteChar(*quote_))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  return true;
}

bool CsvWriterBase::WriteField(Writer& dest, absl::string_view field) {
  for (size_t i = 0; i < field.size(); ++i) {
    if (quotes_needed_[static_cast<unsigned char>(field[i])]) {
      return WriteQuoted(dest, field, i);
    }
  }
  if (ABSL_PREDICT_FALSE(!dest.Write(field))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  return true;
}

bool CsvWriterBase::WriteRecord(const CsvRecord& record) {
  RIEGELI_CHECK(has_header_)
      << "Failed precondition of CsvWriterBase::WriteRecord(CsvRecord): "
         "CsvWriterBase::Options::header() is required";
  if (healthy()) {
    RIEGELI_CHECK_EQ(record.header(), header_)
        << "Failed precondition of CsvWriterBase::WriteRecord(CsvRecord): "
        << "mismatched CSV header and record";
  }
  return WriteRecord(record.fields());
}

}  // namespace riegeli
<commit_msg>Propagate `CsvWriter::header()` from options unconditionally, even if the `Writer` is unhealthy.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "riegeli/csv/csv_writer.h"

#include <stddef.h>

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

#include "absl/base/optimization.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "riegeli/base/base.h"
#include "riegeli/base/object.h"
#include "riegeli/base/status.h"
#include "riegeli/bytes/writer.h"
#include "riegeli/csv/csv_record.h"

namespace riegeli {

void CsvWriterBase::Initialize(Writer* dest, Options&& options) {
  RIEGELI_ASSERT(dest != nullptr)
      << "Failed precondition of CsvWriter: null Writer pointer";
  RIEGELI_ASSERT(options.field_separator() != options.comment())
      << "Field separator conflicts with comment character";
  if (options.quote() != absl::nullopt) {
    RIEGELI_ASSERT(*options.quote() != options.comment())
        << "Quote character conflicts with comment character";
    RIEGELI_ASSERT(*options.quote() != options.field_separator())
        << "Quote character conflicts with field separator";
  }
  if (options.header() != absl::nullopt) {
    has_header_ = true;
    header_ = *std::move(options.header());
  }

  quotes_needed_['\n'] = true;
  quotes_needed_['\r'] = true;
  if (options.comment() != absl::nullopt) {
    quotes_needed_[static_cast<unsigned char>(*options.comment())] = true;
  }
  quotes_needed_[static_cast<unsigned char>(options.field_separator())] = true;
  if (options.quote() != absl::nullopt) {
    quotes_needed_[static_cast<unsigned char>(*options.quote())] = true;
  }
  newline_ = options.newline();
  field_separator_ = options.field_separator();
  quote_ = options.quote();

  if (ABSL_PREDICT_FALSE(!dest->healthy())) {
    FailWithoutAnnotation(AnnotateOverDest(dest->status()));
    return;
  }
  if (has_header_) {
    if (ABSL_PREDICT_TRUE(WriteRecord(header_.names()))) {
      --record_index_;
    }
  }
}

absl::Status CsvWriterBase::AnnotateStatusImpl(absl::Status status) {
  if (is_open()) {
    Writer& dest = *dest_writer();
    status = dest.AnnotateStatus(std::move(status));
  }
  return AnnotateOverDest(std::move(status));
}

absl::Status CsvWriterBase::AnnotateOverDest(absl::Status status) {
  if (!standalone_record_) {
    return Annotate(status, absl::StrCat("at record ", record_index()));
  }
  return status;
}

inline bool CsvWriterBase::WriteQuoted(Writer& dest, absl::string_view field,
                                       size_t already_scanned) {
  if (ABSL_PREDICT_FALSE(quote_ == absl::nullopt)) {
    return Fail(absl::InvalidArgumentError(absl::StrCat(
        "If quoting is turned off, special characters inside fields are not "
        "expressible: '",
        absl::CHexEscape(absl::string_view(&field[already_scanned], 1)), "'")));
  }
  if (ABSL_PREDICT_FALSE(!dest.WriteChar(*quote_))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  const char* start = field.data();
  const char* next_to_check = field.data() + already_scanned;
  const char* const limit = field.data() + field.size();
  // Write characters in the range [`start`..`limit`), except that if quotes are
  // found in the range [`next_to_check`..`limit`), write them twice.
  while (const char* const next_quote = static_cast<const char*>(std::memchr(
             next_to_check, *quote_, PtrDistance(next_to_check, limit)))) {
    if (ABSL_PREDICT_FALSE(
            !dest.Write(start, PtrDistance(start, next_quote + 1)))) {
      return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
    }
    start = next_quote;
    next_to_check = next_quote + 1;
  }
  if (ABSL_PREDICT_FALSE(!dest.Write(start, PtrDistance(start, limit)))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  if (ABSL_PREDICT_FALSE(!dest.WriteChar(*quote_))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  return true;
}

bool CsvWriterBase::WriteField(Writer& dest, absl::string_view field) {
  for (size_t i = 0; i < field.size(); ++i) {
    if (quotes_needed_[static_cast<unsigned char>(field[i])]) {
      return WriteQuoted(dest, field, i);
    }
  }
  if (ABSL_PREDICT_FALSE(!dest.Write(field))) {
    return FailWithoutAnnotation(AnnotateOverDest(dest.status()));
  }
  return true;
}

bool CsvWriterBase::WriteRecord(const CsvRecord& record) {
  RIEGELI_CHECK(has_header_)
      << "Failed precondition of CsvWriterBase::WriteRecord(CsvRecord): "
         "CsvWriterBase::Options::header() is required";
  if (healthy()) {
    RIEGELI_CHECK_EQ(record.header(), header_)
        << "Failed precondition of CsvWriterBase::WriteRecord(CsvRecord): "
        << "mismatched CSV header and record";
  }
  return WriteRecord(record.fields());
}

}  // namespace riegeli
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/utility/source/process_thread_impl.h"

#include "webrtc/base/checks.h"
#include "webrtc/modules/interface/module.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/tick_util.h"

namespace webrtc {
namespace {

// We use this constant internally to signal that a module has requested
// a callback right away.  When this is set, no call to TimeUntilNextProcess
// should be made, but Process() should be called directly.
const int64_t kCallProcessImmediately = -1;

int64_t GetNextCallbackTime(Module* module, int64_t time_now) {
  int64_t interval = module->TimeUntilNextProcess();
  // Currently some implementations erroneously return error codes from
  // TimeUntilNextProcess(). So, as is, we correct that and log an error.
  if (interval < 0) {
    LOG(LS_ERROR) << "TimeUntilNextProcess returned an invalid value "
                  << interval;
    interval = 0;
  }
  return time_now + interval;
}
}

ProcessThread::~ProcessThread() {}

// static
rtc::scoped_ptr<ProcessThread> ProcessThread::Create() {
  return rtc::scoped_ptr<ProcessThread>(new ProcessThreadImpl()).Pass();
}

ProcessThreadImpl::ProcessThreadImpl()
    : wake_up_(EventWrapper::Create()), stop_(false) {
}

ProcessThreadImpl::~ProcessThreadImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!thread_.get());
  DCHECK(!stop_);

  while (!queue_.empty()) {
    delete queue_.front();
    queue_.pop();
  }
}

void ProcessThreadImpl::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!thread_.get());
  if (thread_.get())
    return;

  DCHECK(!stop_);

  for (ModuleCallback& m : modules_)
    m.module->ProcessThreadAttached(this);

  thread_ = ThreadWrapper::CreateThread(
      &ProcessThreadImpl::Run, this, "ProcessThread");
  CHECK(thread_->Start());
}

void ProcessThreadImpl::Stop() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if(!thread_.get())
    return;

  {
    rtc::CritScope lock(&lock_);
    stop_ = true;
  }

  wake_up_->Set();

  CHECK(thread_->Stop());
  thread_.reset();
  stop_ = false;

  for (ModuleCallback& m : modules_)
    m.module->ProcessThreadAttached(nullptr);
}

void ProcessThreadImpl::WakeUp(Module* module) {
  // Allowed to be called on any thread.
  {
    rtc::CritScope lock(&lock_);
    for (ModuleCallback& m : modules_) {
      if (m.module == module)
        m.next_callback = kCallProcessImmediately;
    }
  }
  wake_up_->Set();
}

void ProcessThreadImpl::PostTask(rtc::scoped_ptr<ProcessTask> task) {
  // Allowed to be called on any thread.
  {
    rtc::CritScope lock(&lock_);
    queue_.push(task.release());
  }
  wake_up_->Set();
}

void ProcessThreadImpl::RegisterModule(Module* module) {
  // Allowed to be called on any thread.
  DCHECK(module);

#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
  {
    // Catch programmer error.
    rtc::CritScope lock(&lock_);
    for (const ModuleCallback& mc : modules_)
      DCHECK(mc.module != module);
  }
#endif

  // Now that we know the module isn't in the list, we'll call out to notify
  // the module that it's attached to the worker thread.  We don't hold
  // the lock while we make this call.
  if (thread_.get())
    module->ProcessThreadAttached(this);

  {
    rtc::CritScope lock(&lock_);
    modules_.push_back(ModuleCallback(module));
  }

  // Wake the thread calling ProcessThreadImpl::Process() to update the
  // waiting time. The waiting time for the just registered module may be
  // shorter than all other registered modules.
  wake_up_->Set();
}

void ProcessThreadImpl::DeRegisterModule(Module* module) {
  // Allowed to be called on any thread.
  DCHECK(module);
  {
    rtc::CritScope lock(&lock_);
    modules_.remove_if([&module](const ModuleCallback& m) {
        return m.module == module;
      });
  }

  // Notify the module that it's been detached, while not holding the lock.
  if (thread_.get())
    module->ProcessThreadAttached(nullptr);
}

// static
bool ProcessThreadImpl::Run(void* obj) {
  return static_cast<ProcessThreadImpl*>(obj)->Process();
}

bool ProcessThreadImpl::Process() {
  int64_t now = TickTime::MillisecondTimestamp();
  int64_t next_checkpoint = now + (1000 * 60);

  {
    rtc::CritScope lock(&lock_);
    if (stop_)
      return false;
    for (ModuleCallback& m : modules_) {
      // TODO(tommi): Would be good to measure the time TimeUntilNextProcess
      // takes and dcheck if it takes too long (e.g. >=10ms).  Ideally this
      // operation should not require taking a lock, so querying all modules
      // should run in a matter of nanoseconds.
      if (m.next_callback == 0)
        m.next_callback = GetNextCallbackTime(m.module, now);

      if (m.next_callback <= now ||
          m.next_callback == kCallProcessImmediately) {
        m.module->Process();
        // Use a new 'now' reference to calculate when the next callback
        // should occur.  We'll continue to use 'now' above for the baseline
        // of calculating how long we should wait, to reduce variance.
        int64_t new_now = TickTime::MillisecondTimestamp();
        m.next_callback = GetNextCallbackTime(m.module, new_now);
      }

      if (m.next_callback < next_checkpoint)
        next_checkpoint = m.next_callback;
    }

    while (!queue_.empty()) {
      ProcessTask* task = queue_.front();
      queue_.pop();
      lock_.Leave();
      task->Run();
      delete task;
      lock_.Enter();
    }
  }

  int64_t time_to_wait = next_checkpoint - TickTime::MillisecondTimestamp();
  if (time_to_wait > 0)
    wake_up_->Wait(static_cast<unsigned long>(time_to_wait));

  return true;
}
}  // namespace webrtc
<commit_msg>Add locks to Start(), Stop() methods in ProcessThread. This is necessary unfortunately since there are a few places where DeRegisterModule does not reliably occur on the same thread.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/utility/source/process_thread_impl.h"

#include "webrtc/base/checks.h"
#include "webrtc/modules/interface/module.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/tick_util.h"

namespace webrtc {
namespace {

// We use this constant internally to signal that a module has requested
// a callback right away.  When this is set, no call to TimeUntilNextProcess
// should be made, but Process() should be called directly.
const int64_t kCallProcessImmediately = -1;

int64_t GetNextCallbackTime(Module* module, int64_t time_now) {
  int64_t interval = module->TimeUntilNextProcess();
  // Currently some implementations erroneously return error codes from
  // TimeUntilNextProcess(). So, as is, we correct that and log an error.
  if (interval < 0) {
    LOG(LS_ERROR) << "TimeUntilNextProcess returned an invalid value "
                  << interval;
    interval = 0;
  }
  return time_now + interval;
}
}

ProcessThread::~ProcessThread() {}

// static
rtc::scoped_ptr<ProcessThread> ProcessThread::Create() {
  return rtc::scoped_ptr<ProcessThread>(new ProcessThreadImpl()).Pass();
}

ProcessThreadImpl::ProcessThreadImpl()
    : wake_up_(EventWrapper::Create()), stop_(false) {
}

ProcessThreadImpl::~ProcessThreadImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!thread_.get());
  DCHECK(!stop_);

  while (!queue_.empty()) {
    delete queue_.front();
    queue_.pop();
  }
}

void ProcessThreadImpl::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!thread_.get());
  if (thread_.get())
    return;

  DCHECK(!stop_);

  {
    // TODO(tommi): Since DeRegisterModule is currently being called from
    // different threads in some cases (ChannelOwner), we need to lock access to
    // the modules_ collection even on the controller thread.
    // Once we've cleaned up those places, we can remove this lock.
    rtc::CritScope lock(&lock_);
    for (ModuleCallback& m : modules_)
      m.module->ProcessThreadAttached(this);
  }

  thread_ = ThreadWrapper::CreateThread(
      &ProcessThreadImpl::Run, this, "ProcessThread");
  CHECK(thread_->Start());
}

void ProcessThreadImpl::Stop() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if(!thread_.get())
    return;

  {
    rtc::CritScope lock(&lock_);
    stop_ = true;
  }

  wake_up_->Set();

  CHECK(thread_->Stop());
  thread_.reset();
  stop_ = false;

  // TODO(tommi): Since DeRegisterModule is currently being called from
  // different threads in some cases (ChannelOwner), we need to lock access to
  // the modules_ collection even on the controller thread.
  // Once we've cleaned up those places, we can remove this lock.
  rtc::CritScope lock(&lock_);
  for (ModuleCallback& m : modules_)
    m.module->ProcessThreadAttached(nullptr);
}

void ProcessThreadImpl::WakeUp(Module* module) {
  // Allowed to be called on any thread.
  // TODO(tommi): Disallow this ^^^
  {
    rtc::CritScope lock(&lock_);
    for (ModuleCallback& m : modules_) {
      if (m.module == module)
        m.next_callback = kCallProcessImmediately;
    }
  }
  wake_up_->Set();
}

void ProcessThreadImpl::PostTask(rtc::scoped_ptr<ProcessTask> task) {
  // Allowed to be called on any thread.
  // TODO(tommi): Disallow this ^^^
  {
    rtc::CritScope lock(&lock_);
    queue_.push(task.release());
  }
  wake_up_->Set();
}

void ProcessThreadImpl::RegisterModule(Module* module) {
  // Allowed to be called on any thread.
  DCHECK(module);

#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
  {
    // Catch programmer error.
    rtc::CritScope lock(&lock_);
    for (const ModuleCallback& mc : modules_)
      DCHECK(mc.module != module);
  }
#endif

  // Now that we know the module isn't in the list, we'll call out to notify
  // the module that it's attached to the worker thread.  We don't hold
  // the lock while we make this call.
  if (thread_.get())
    module->ProcessThreadAttached(this);

  {
    rtc::CritScope lock(&lock_);
    modules_.push_back(ModuleCallback(module));
  }

  // Wake the thread calling ProcessThreadImpl::Process() to update the
  // waiting time. The waiting time for the just registered module may be
  // shorter than all other registered modules.
  wake_up_->Set();
}

void ProcessThreadImpl::DeRegisterModule(Module* module) {
  // Allowed to be called on any thread.
  DCHECK(module);
  {
    rtc::CritScope lock(&lock_);
    modules_.remove_if([&module](const ModuleCallback& m) {
        return m.module == module;
      });
  }

  // Notify the module that it's been detached, while not holding the lock.
  if (thread_.get())
    module->ProcessThreadAttached(nullptr);
}

// static
bool ProcessThreadImpl::Run(void* obj) {
  return static_cast<ProcessThreadImpl*>(obj)->Process();
}

bool ProcessThreadImpl::Process() {
  int64_t now = TickTime::MillisecondTimestamp();
  int64_t next_checkpoint = now + (1000 * 60);

  {
    rtc::CritScope lock(&lock_);
    if (stop_)
      return false;
    for (ModuleCallback& m : modules_) {
      // TODO(tommi): Would be good to measure the time TimeUntilNextProcess
      // takes and dcheck if it takes too long (e.g. >=10ms).  Ideally this
      // operation should not require taking a lock, so querying all modules
      // should run in a matter of nanoseconds.
      if (m.next_callback == 0)
        m.next_callback = GetNextCallbackTime(m.module, now);

      if (m.next_callback <= now ||
          m.next_callback == kCallProcessImmediately) {
        m.module->Process();
        // Use a new 'now' reference to calculate when the next callback
        // should occur.  We'll continue to use 'now' above for the baseline
        // of calculating how long we should wait, to reduce variance.
        int64_t new_now = TickTime::MillisecondTimestamp();
        m.next_callback = GetNextCallbackTime(m.module, new_now);
      }

      if (m.next_callback < next_checkpoint)
        next_checkpoint = m.next_callback;
    }

    while (!queue_.empty()) {
      ProcessTask* task = queue_.front();
      queue_.pop();
      lock_.Leave();
      task->Run();
      delete task;
      lock_.Enter();
    }
  }

  int64_t time_to_wait = next_checkpoint - TickTime::MillisecondTimestamp();
  if (time_to_wait > 0)
    wake_up_->Wait(static_cast<unsigned long>(time_to_wait));

  return true;
}
}  // namespace webrtc
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <test/unit/lang/utility.hpp>

TEST(langParserVarDeclsGrammarDef, addVar) {
  test_throws("validate_add_var_bad1",
              "duplicate declaration of variable");
  test_throws("validate_add_var_bad2",
              "integer parameters or transformed parameters are not allowed");
  test_parsable("validate_add_var_good");
}

TEST(langParserVarDeclsGrammarDef, validateIntExpr) {
  test_parsable("validate_validate_int_expr_good");
  for (int i = 1; i <= 13; ++i) {
    std::string model_name("validate_validate_int_expr_bad");
    model_name += boost::lexical_cast<std::string>(i);
    test_throws(model_name,
                "expression denoting integer required");
  }
}

TEST(langParserVarDeclsGrammarDef, setIntRangeLower) {
  test_parsable("validate_set_int_range_lower_good");
  test_throws("validate_set_int_range_lower_bad1",
              "expression denoting integer required");
  test_throws("validate_set_int_range_lower_bad2",
              "expression denoting integer required");
  test_throws("validate_set_int_range_lower_bad3",
              "expression denoting integer required");
}

TEST(langParserVarDeclsGrammarDef, setIntRangeUpper) {
  test_parsable("validate_set_int_range_upper_good");
  test_throws("validate_set_int_range_upper_bad1",
              "expression denoting integer required");
  test_throws("validate_set_int_range_upper_bad2",
              "expression denoting integer required");
}

TEST(langParserVarDeclsGrammarDef, setDoubleRangeLower) {
  test_parsable("validate_set_double_range_lower_good");
  test_throws("validate_set_double_range_lower_bad1",
              "expression denoting real required");
  test_throws("validate_set_double_range_lower_bad2",
              "expression denoting real required");
}

TEST(langParserVarDeclsGrammarDef, setDoubleRangeUpper) {
  test_parsable("validate_set_double_range_upper_good");
  test_throws("validate_set_double_range_upper_bad1",
              "expression denoting real required");
  test_throws("validate_set_double_range_upper_bad2",
              "expression denoting real required");
}

TEST(langParserVarDeclsGrammarDef, parametersInLocals) {
  // test_parsable("var-decls-in-functions");
  test_throws("var-decl-bad-1",
              "non-data variables not allowed in dimension declarations");
}

TEST(langParserVarDeclsGrammarDef, constraintsInLocals) {
  test_throws("local_var_constraint",
              "require unconstrained. found range constraint.");
  test_throws("local_var_constraint2",
              "require unconstrained. found range constraint.");
  test_throws("local_var_constraint3",
              "require unconstrained. found range constraint.");
}

TEST (langParserVarDeclsGrammarDef, zeroVecs) {
  test_parsable("vector-zero");
}

TEST(langParserVarDeclsGrammarDef, defDeclIntVar) {
  test_parsable("declare-define-var-int");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar1) {
  test_throws("declare-define-var-int-1",
              "variable definition base type mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar2) {
  test_throws("declare-define-var-int-2",
              "variable definition base type mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar3) {
  test_throws("declare-define-var-int-3",
              "variable definition dimensions mismatch");
}

TEST(langParserVarDeclsGrammarDef, defDeclDoubleVar) {
  test_parsable("declare-define-var-double");
}

TEST(langParserVarDeclsGrammarDef, defDeclVecTypesVar) {
  test_parsable("declare-define-var-vec-types");
}

TEST(langParserVarDeclsGrammarDef, defDeclMatrixVar) {
  test_parsable("declare-define-var-matrix");
}
<commit_msg>more unit tests<commit_after>#include <gtest/gtest.h>
#include <test/unit/lang/utility.hpp>

TEST(langParserVarDeclsGrammarDef, addVar) {
  test_throws("validate_add_var_bad1",
              "duplicate declaration of variable");
  test_throws("validate_add_var_bad2",
              "integer parameters or transformed parameters are not allowed");
  test_parsable("validate_add_var_good");
}

TEST(langParserVarDeclsGrammarDef, validateIntExpr) {
  test_parsable("validate_validate_int_expr_good");
  for (int i = 1; i <= 13; ++i) {
    std::string model_name("validate_validate_int_expr_bad");
    model_name += boost::lexical_cast<std::string>(i);
    test_throws(model_name,
                "expression denoting integer required");
  }
}

TEST(langParserVarDeclsGrammarDef, setIntRangeLower) {
  test_parsable("validate_set_int_range_lower_good");
  test_throws("validate_set_int_range_lower_bad1",
              "expression denoting integer required");
  test_throws("validate_set_int_range_lower_bad2",
              "expression denoting integer required");
  test_throws("validate_set_int_range_lower_bad3",
              "expression denoting integer required");
}

TEST(langParserVarDeclsGrammarDef, setIntRangeUpper) {
  test_parsable("validate_set_int_range_upper_good");
  test_throws("validate_set_int_range_upper_bad1",
              "expression denoting integer required");
  test_throws("validate_set_int_range_upper_bad2",
              "expression denoting integer required");
}

TEST(langParserVarDeclsGrammarDef, setDoubleRangeLower) {
  test_parsable("validate_set_double_range_lower_good");
  test_throws("validate_set_double_range_lower_bad1",
              "expression denoting real required");
  test_throws("validate_set_double_range_lower_bad2",
              "expression denoting real required");
}

TEST(langParserVarDeclsGrammarDef, setDoubleRangeUpper) {
  test_parsable("validate_set_double_range_upper_good");
  test_throws("validate_set_double_range_upper_bad1",
              "expression denoting real required");
  test_throws("validate_set_double_range_upper_bad2",
              "expression denoting real required");
}

TEST(langParserVarDeclsGrammarDef, parametersInLocals) {
  // test_parsable("var-decls-in-functions");
  test_throws("var-decl-bad-1",
              "non-data variables not allowed in dimension declarations");
}

TEST(langParserVarDeclsGrammarDef, constraintsInLocals) {
  test_throws("local_var_constraint",
              "require unconstrained. found range constraint.");
  test_throws("local_var_constraint2",
              "require unconstrained. found range constraint.");
  test_throws("local_var_constraint3",
              "require unconstrained. found range constraint.");
}

TEST (langParserVarDeclsGrammarDef, zeroVecs) {
  test_parsable("vector-zero");
}

TEST(langParserVarDeclsGrammarDef, defDeclIntVar) {
  test_parsable("declare-define-var-int");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar1) {
  test_throws("declare-define-var-int-1",
              "variable definition base type mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar2) {
  test_throws("declare-define-var-int-2",
              "variable definition base type mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar3) {
  test_throws("declare-define-var-int-3",
              "variable definition dimensions mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclIntVar4) {
  test_throws("declare-define-var-int-4",
              "variable definition dimensions mismatch");
}

TEST(langParserVarDeclsGrammarDef, defDeclDoubleVar) {
  test_parsable("declare-define-var-double");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclDoubleVar1) {
  test_throws("declare-define-var-double-1",
              "variable definition dimensions mismatch");
}

TEST(langParserVarDeclsGrammarDef, badDefDeclDoubleVar2) {
  test_throws("declare-define-var-double-2",
              "variable definition base type mismatch");
}

TEST(langParserVarDeclsGrammarDef, defDeclVecTypesVar) {
  test_parsable("declare-define-var-vec-types");
}

TEST(langParserVarDeclsGrammarDef, defDeclMatrixVar) {
  test_parsable("declare-define-var-matrix");
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <iterator>
#include <sstream>
#include "LoaderMTL.hpp"
#include "Cache.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace assets
    {
        LoaderMTL::LoaderMTL():
            Loader({"mtl"})
        {
        }

        bool LoaderMTL::loadAsset(const std::string& filename, const std::vector<uint8_t>& data)
        {
            std::stringstream stream;
            std::copy(data.begin(), data.end(), std::ostream_iterator<uint8_t>(stream));

            std::string name = filename;
            std::shared_ptr<graphics::Texture> diffuseTexture;
            std::shared_ptr<graphics::Texture> ambientTexture;
            Color diffuseColor = Color::WHITE;
            float opacity = 1.0f;

            uint32_t materialCount = 0;
            std::string read;

            for (std::string line; std::getline(stream, line);)
            {
                if (!line.empty())
                {
                    if (line[0] == '#') continue; // comment

                    std::stringstream lineStream;
                    lineStream << line;

                    lineStream >> read;

                    if (read == "newmtl")
                    {
                        if (materialCount)
                        {
                            std::shared_ptr<graphics::Material> material = std::make_shared<graphics::Material>();
                            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
                            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
                            material->textures[0] = diffuseTexture;
                            material->textures[1] = ambientTexture;
                            material->diffuseColor = diffuseColor;
                            material->opacity = opacity;

                            engine->getCache()->setMaterial(name, material);
                        }

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse material name";
                            return false;
                        }

                        lineStream >> read;

                        name = read;
                        diffuseTexture.reset();
                        ambientTexture.reset();
                        diffuseColor = Color::WHITE;
                        opacity = 1.0f;
                    }
                    else if (read == "map_Ka") // ambient texture map
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse ambient texture file name";
                            return false;
                        }

                        lineStream >> read;

                        ambientTexture = engine->getCache()->getTexture(read);
                    }
                    else if (read == "map_Kd") // diffuse texture map
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse texture file name";
                            return false;
                        }

                        lineStream >> read;

                        diffuseTexture = engine->getCache()->getTexture(read);
                    }
                    else if (read == "Ka") // ambient color
                    {

                    }
                    else if (read == "Kd") // diffuse color
                    {
                        float color[4];
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[0];

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[1];

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[2];
                        color[3] = 1.0f;

                        diffuseColor = Color(color);
                    }
                    else if (read == "Ks") // specular color
                    {

                    }
                    else if (read == "Ke") // emissive color
                    {

                    }
                    else if (read == "d") // opacity
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse opacity";
                            return false;
                        }

                        lineStream >> opacity;
                    }
                    else if (read == "Tr") // transparency
                    {
                        float transparency;

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse transparency";
                            return false;
                        }

                        lineStream >> transparency;

                        // d = 1 - Tr
                        opacity = 1.0f - transparency;
                    }

                    if (!materialCount) ++materialCount; // if we got at least one attribute, we have an material
                }
            }

            if (materialCount)
            {
                std::shared_ptr<graphics::Material> material = std::make_shared<graphics::Material>();
                material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
                material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
                material->textures[0] = diffuseTexture;
                material->textures[1] = ambientTexture;
                material->diffuseColor = diffuseColor;
                material->opacity = opacity;

                engine->getCache()->setMaterial(name, material);
            }

            return true;
        }
    } // namespace assets
} // namespace ouzel
<commit_msg>Enable mipmapping for MTL textures<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <iterator>
#include <sstream>
#include "LoaderMTL.hpp"
#include "Cache.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace assets
    {
        LoaderMTL::LoaderMTL():
            Loader({"mtl"})
        {
        }

        bool LoaderMTL::loadAsset(const std::string& filename, const std::vector<uint8_t>& data)
        {
            std::stringstream stream;
            std::copy(data.begin(), data.end(), std::ostream_iterator<uint8_t>(stream));

            std::string name = filename;
            std::shared_ptr<graphics::Texture> diffuseTexture;
            std::shared_ptr<graphics::Texture> ambientTexture;
            Color diffuseColor = Color::WHITE;
            float opacity = 1.0f;

            uint32_t materialCount = 0;
            std::string read;

            for (std::string line; std::getline(stream, line);)
            {
                if (!line.empty())
                {
                    if (line[0] == '#') continue; // comment

                    std::stringstream lineStream;
                    lineStream << line;

                    lineStream >> read;

                    if (read == "newmtl")
                    {
                        if (materialCount)
                        {
                            std::shared_ptr<graphics::Material> material = std::make_shared<graphics::Material>();
                            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
                            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
                            material->textures[0] = diffuseTexture;
                            material->textures[1] = ambientTexture;
                            material->diffuseColor = diffuseColor;
                            material->opacity = opacity;

                            engine->getCache()->setMaterial(name, material);
                        }

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse material name";
                            return false;
                        }

                        lineStream >> read;

                        name = read;
                        diffuseTexture.reset();
                        ambientTexture.reset();
                        diffuseColor = Color::WHITE;
                        opacity = 1.0f;
                    }
                    else if (read == "map_Ka") // ambient texture map
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse ambient texture file name";
                            return false;
                        }

                        lineStream >> read;

                        ambientTexture = engine->getCache()->getTexture(read, false, true);
                    }
                    else if (read == "map_Kd") // diffuse texture map
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse texture file name";
                            return false;
                        }

                        lineStream >> read;

                        diffuseTexture = engine->getCache()->getTexture(read, false, true);
                    }
                    else if (read == "Ka") // ambient color
                    {

                    }
                    else if (read == "Kd") // diffuse color
                    {
                        float color[4];
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[0];

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[1];

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse diffuse color";
                            return false;
                        }

                        lineStream >> color[2];
                        color[3] = 1.0f;

                        diffuseColor = Color(color);
                    }
                    else if (read == "Ks") // specular color
                    {

                    }
                    else if (read == "Ke") // emissive color
                    {

                    }
                    else if (read == "d") // opacity
                    {
                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse opacity";
                            return false;
                        }

                        lineStream >> opacity;
                    }
                    else if (read == "Tr") // transparency
                    {
                        float transparency;

                        if (lineStream.eof())
                        {
                            Log(Log::Level::ERR) << "Failed to parse transparency";
                            return false;
                        }

                        lineStream >> transparency;

                        // d = 1 - Tr
                        opacity = 1.0f - transparency;
                    }

                    if (!materialCount) ++materialCount; // if we got at least one attribute, we have an material
                }
            }

            if (materialCount)
            {
                std::shared_ptr<graphics::Material> material = std::make_shared<graphics::Material>();
                material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
                material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
                material->textures[0] = diffuseTexture;
                material->textures[1] = ambientTexture;
                material->diffuseColor = diffuseColor;
                material->opacity = opacity;

                engine->getCache()->setMaterial(name, material);
            }

            return true;
        }
    } // namespace assets
} // namespace ouzel
<|endoftext|>


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

#ifndef _XMLOFF_XMLSECTIONSOURCEIMPORTCONTEXT_HXX_
#define _XMLOFF_XMLSECTIONSOURCEIMPORTCONTEXT_HXX_

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif

namespace com { namespace sun { namespace star {
    namespace beans { class XPropertySet; }
    namespace xml { namespace sax { class XAttributeList; } }
} } }
namespace rtl { class OUString; }

class XMLSectionSourceImportContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & rSectionPropertySet;

public:

    TYPEINFO();

    XMLSectionSourceImportContext(
        SvXMLImport& rImport,
        sal_uInt16 nPrfx,
        const ::rtl::OUString& rLocalName,
        ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rSectPropSet);

    ~XMLSectionSourceImportContext();

protected:

    virtual void StartElement(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList> & xAttrList);

    virtual void EndElement();

    virtual SvXMLImportContext *CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList> & xAttrList );
};

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.654); FILE MERGED 2005/09/05 14:40:01 rt 1.1.654.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLSectionSourceImportContext.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:18:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLSECTIONSOURCEIMPORTCONTEXT_HXX_
#define _XMLOFF_XMLSECTIONSOURCEIMPORTCONTEXT_HXX_

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif

namespace com { namespace sun { namespace star {
    namespace beans { class XPropertySet; }
    namespace xml { namespace sax { class XAttributeList; } }
} } }
namespace rtl { class OUString; }

class XMLSectionSourceImportContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & rSectionPropertySet;

public:

    TYPEINFO();

    XMLSectionSourceImportContext(
        SvXMLImport& rImport,
        sal_uInt16 nPrfx,
        const ::rtl::OUString& rLocalName,
        ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet> & rSectPropSet);

    ~XMLSectionSourceImportContext();

protected:

    virtual void StartElement(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList> & xAttrList);

    virtual void EndElement();

    virtual SvXMLImportContext *CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList> & xAttrList );
};

#endif
<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "Engine.h"
#include "RendererOGL.h"
#include "FileSystem.h"
#include "ShaderOGL.h"
#include "Utils.h"

namespace ouzel
{
    namespace graphics
    {
        ShaderOGL::ShaderOGL():
            Shader()
        {
        }

        ShaderOGL::~ShaderOGL()
        {
            destroy();
        }

        void ShaderOGL::destroy()
        {
            if (programId)
            {
                glDeleteProgram(programId);
                programId = 0;
            }

            if (vertexShaderId)
            {
                glDeleteShader(vertexShaderId);
                vertexShaderId = 0;
            }

            if (pixelShaderId)
            {
                glDeleteShader(pixelShaderId);
                pixelShaderId = 0;
            }
        }

        bool ShaderOGL::initFromBuffers(const uint8_t* pixelShader,
                                        uint32_t pixelShaderSize,
                                        const uint8_t* vertexShader,
                                        uint32_t vertexShaderSize,
                                        uint32_t vertexAttributes,
                                        const std::string& pixelShaderFunction,
                                        const std::string& vertexShaderFunction)
        {
            if (!Shader::initFromBuffers(pixelShader, pixelShaderSize, vertexShader, vertexShaderSize, vertexAttributes, pixelShaderFunction, vertexShaderFunction))
            {
                return false;
            }

            destroy();

            pixelShaderId = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(pixelShaderId, 1, reinterpret_cast<const GLchar**>(&pixelShader), reinterpret_cast<const GLint*>(&pixelShaderSize));
            glCompileShader(pixelShaderId);

            printShaderMessage(pixelShaderId);

            GLint status;
            glGetShaderiv(pixelShaderId, GL_COMPILE_STATUS, &status);
            if (status == GL_FALSE)
            {
                return false;
            }

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertexShaderId, 1, reinterpret_cast<const GLchar**>(&vertexShader), reinterpret_cast<const GLint*>(&vertexShaderSize));
            glCompileShader(vertexShaderId);

            printShaderMessage(vertexShaderId);

            glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status);
            if (status == GL_FALSE)
            {
                log("Failed to link shader");
                return false;
            }

            programId = glCreateProgram();
            glAttachShader(programId, vertexShaderId);
            glAttachShader(programId, pixelShaderId);

            GLuint index = 0;

            if (vertexAttributes & VERTEX_POSITION)
            {
                glBindAttribLocation(programId, index, "in_Position");
                ++index;
            }

            if (vertexAttributes & VERTEX_COLOR)
            {
                glBindAttribLocation(programId, index, "in_Color");
                ++index;
            }

            if (vertexAttributes & VERTEX_NORMAL)
            {
                glBindAttribLocation(programId, index, "in_Normal");
                ++index;
            }

            if (vertexAttributes & VERTEX_TEXCOORD0)
            {
                glBindAttribLocation(programId, index, "in_TexCoord0");
                ++index;
            }

            if (vertexAttributes & VERTEX_TEXCOORD1)
            {
                glBindAttribLocation(programId, index, "in_TexCoord1");
                ++index;
            }

            glLinkProgram(programId);

            printProgramMessage();

            glGetProgramiv(programId, GL_LINK_STATUS, &status);
            if (status == GL_FALSE)
            {
                return false;
            }

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            RendererOGL::bindProgram(programId);

            GLint texture0Location = glGetUniformLocation(programId, "texture0");
            if (texture0Location != -1) glUniform1i(texture0Location, 0);

            GLint texture1Location = glGetUniformLocation(programId, "texture1");
            if (texture1Location != -1) glUniform1i(texture1Location, 1);

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            glDetachShader(programId, vertexShaderId);
            glDeleteShader(vertexShaderId);
            vertexShaderId = 0;

            glDetachShader(programId, pixelShaderId);
            glDeleteShader(pixelShaderId);
            pixelShaderId = 0;

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            return true;
        }

        void ShaderOGL::printShaderMessage(GLuint shaderId)
        {
            GLint logLength = 0;
            glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);

            if (logLength > 0)
            {
                std::vector<char> logMessage(logLength);
                glGetShaderInfoLog(shaderId, logLength, nullptr, logMessage.data());

                log("Shader compilation error: %s", logMessage.data());
            }
        }

        void ShaderOGL::printProgramMessage()
        {
            GLint logLength = 0;
            glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLength);

            if (logLength > 0)
            {
                std::vector<char> logMessage(logLength);
                glGetProgramInfoLog(programId, logLength, nullptr, logMessage.data());

                log("Shader linking error: %s", logMessage.data());
            }
        }

        bool ShaderOGL::setPixelShaderConstantInfo(const std::vector<ConstantInfo>& constantInfo, uint32_t alignment)
        {
            Shader::setPixelShaderConstantInfo(constantInfo, alignment);

            pixelShaderConstantLocations.reserve(constantInfo.size());

            for (const ConstantInfo& info : pixelShaderConstantInfo)
            {
                GLint location = glGetUniformLocation(programId, info.name.c_str());

                if (location == -1)
                {
                    RendererOGL::checkOpenGLErrors();
                    return false;
                }

                pixelShaderConstantLocations.push_back(location);
            }

            return true;
        }

        bool ShaderOGL::setVertexShaderConstantInfo(const std::vector<ConstantInfo>& constantInfo, uint32_t alignment)
        {
            Shader::setVertexShaderConstantInfo(constantInfo, alignment);

            vertexShaderConstantLocations.reserve(constantInfo.size());

            for (const ConstantInfo& info : vertexShaderConstantInfo)
            {
                GLint location = glGetUniformLocation(programId, info.name.c_str());

                if (location == -1)
                {
                    RendererOGL::checkOpenGLErrors();
                    return false;
                }

                vertexShaderConstantLocations.push_back(location);
            }

            return true;
        }

        bool ShaderOGL::setPixelShaderConstant(uint32_t index, uint32_t size, uint32_t count, const float* value)
        {
            if (index >= pixelShaderConstantLocations.size()) return false;

            RendererOGL::bindProgram(programId);

            GLint location = pixelShaderConstantLocations[index];

            uint32_t components = size / 4;

            switch (components)
            {
                case 1:
                    glUniform1fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 2:
                    glUniform2fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 3:
                    glUniform3fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 4:
                    glUniform4fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 9:
                    glUniformMatrix3fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                case 16:
                    glUniformMatrix4fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                default:
                    log("Unsupported uniform size");
                    return false;
            }

            return true;
        }

        bool ShaderOGL::setVertexShaderConstant(uint32_t index, uint32_t size, uint32_t count, const float* value)
        {
            if (index >= vertexShaderConstantLocations.size()) return false;

            RendererOGL::bindProgram(programId);

            GLint location = vertexShaderConstantLocations[index];

            uint32_t components = size / 4;

            switch (components)
            {
                case 1:
                    glUniform1fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 2:
                    glUniform2fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 3:
                    glUniform3fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 4:
                    glUniform4fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 9:
                    glUniformMatrix3fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                case 16:
                    glUniformMatrix4fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                default:
                    log("Unsupported uniform size");
                    return false;
            }

            return true;
        }
    } // namespace graphics
} // namespace ouzel
<commit_msg>Print error messages only if OpenGL shader compilation or linking failed<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "Engine.h"
#include "RendererOGL.h"
#include "FileSystem.h"
#include "ShaderOGL.h"
#include "Utils.h"

namespace ouzel
{
    namespace graphics
    {
        ShaderOGL::ShaderOGL():
            Shader()
        {
        }

        ShaderOGL::~ShaderOGL()
        {
            destroy();
        }

        void ShaderOGL::destroy()
        {
            if (programId)
            {
                glDeleteProgram(programId);
                programId = 0;
            }

            if (vertexShaderId)
            {
                glDeleteShader(vertexShaderId);
                vertexShaderId = 0;
            }

            if (pixelShaderId)
            {
                glDeleteShader(pixelShaderId);
                pixelShaderId = 0;
            }
        }

        bool ShaderOGL::initFromBuffers(const uint8_t* pixelShader,
                                        uint32_t pixelShaderSize,
                                        const uint8_t* vertexShader,
                                        uint32_t vertexShaderSize,
                                        uint32_t vertexAttributes,
                                        const std::string& pixelShaderFunction,
                                        const std::string& vertexShaderFunction)
        {
            if (!Shader::initFromBuffers(pixelShader, pixelShaderSize, vertexShader, vertexShaderSize, vertexAttributes, pixelShaderFunction, vertexShaderFunction))
            {
                return false;
            }

            destroy();

            pixelShaderId = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(pixelShaderId, 1, reinterpret_cast<const GLchar**>(&pixelShader), reinterpret_cast<const GLint*>(&pixelShaderSize));
            glCompileShader(pixelShaderId);

            GLint status;
            glGetShaderiv(pixelShaderId, GL_COMPILE_STATUS, &status);
            if (status == GL_FALSE)
            {
            printShaderMessage(pixelShaderId);
                return false;
            }

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertexShaderId, 1, reinterpret_cast<const GLchar**>(&vertexShader), reinterpret_cast<const GLint*>(&vertexShaderSize));
            glCompileShader(vertexShaderId);

            glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status);
            if (status == GL_FALSE)
            {
                printShaderMessage(vertexShaderId);
                log("Failed to link shader");
                return false;
            }

            programId = glCreateProgram();
            glAttachShader(programId, vertexShaderId);
            glAttachShader(programId, pixelShaderId);

            GLuint index = 0;

            if (vertexAttributes & VERTEX_POSITION)
            {
                glBindAttribLocation(programId, index, "in_Position");
                ++index;
            }

            if (vertexAttributes & VERTEX_COLOR)
            {
                glBindAttribLocation(programId, index, "in_Color");
                ++index;
            }

            if (vertexAttributes & VERTEX_NORMAL)
            {
                glBindAttribLocation(programId, index, "in_Normal");
                ++index;
            }

            if (vertexAttributes & VERTEX_TEXCOORD0)
            {
                glBindAttribLocation(programId, index, "in_TexCoord0");
                ++index;
            }

            if (vertexAttributes & VERTEX_TEXCOORD1)
            {
                glBindAttribLocation(programId, index, "in_TexCoord1");
                ++index;
            }

            glLinkProgram(programId);

            glGetProgramiv(programId, GL_LINK_STATUS, &status);
            if (status == GL_FALSE)
            {
                printProgramMessage();
                return false;
            }

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            RendererOGL::bindProgram(programId);

            GLint texture0Location = glGetUniformLocation(programId, "texture0");
            if (texture0Location != -1) glUniform1i(texture0Location, 0);

            GLint texture1Location = glGetUniformLocation(programId, "texture1");
            if (texture1Location != -1) glUniform1i(texture1Location, 1);

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            glDetachShader(programId, vertexShaderId);
            glDeleteShader(vertexShaderId);
            vertexShaderId = 0;

            glDetachShader(programId, pixelShaderId);
            glDeleteShader(pixelShaderId);
            pixelShaderId = 0;

            if (std::static_pointer_cast<RendererOGL>(sharedEngine->getRenderer())->checkOpenGLErrors())
            {
                return false;
            }

            return true;
        }

        void ShaderOGL::printShaderMessage(GLuint shaderId)
        {
            GLint logLength = 0;
            glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);

            if (logLength > 0)
            {
                std::vector<char> logMessage(logLength);
                glGetShaderInfoLog(shaderId, logLength, nullptr, logMessage.data());

                log("Shader compilation error: %s", logMessage.data());
            }
        }

        void ShaderOGL::printProgramMessage()
        {
            GLint logLength = 0;
            glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLength);

            if (logLength > 0)
            {
                std::vector<char> logMessage(logLength);
                glGetProgramInfoLog(programId, logLength, nullptr, logMessage.data());

                log("Shader linking error: %s", logMessage.data());
            }
        }

        bool ShaderOGL::setPixelShaderConstantInfo(const std::vector<ConstantInfo>& constantInfo, uint32_t alignment)
        {
            Shader::setPixelShaderConstantInfo(constantInfo, alignment);

            pixelShaderConstantLocations.reserve(constantInfo.size());

            for (const ConstantInfo& info : pixelShaderConstantInfo)
            {
                GLint location = glGetUniformLocation(programId, info.name.c_str());

                if (location == -1)
                {
                    RendererOGL::checkOpenGLErrors();
                    return false;
                }

                pixelShaderConstantLocations.push_back(location);
            }

            return true;
        }

        bool ShaderOGL::setVertexShaderConstantInfo(const std::vector<ConstantInfo>& constantInfo, uint32_t alignment)
        {
            Shader::setVertexShaderConstantInfo(constantInfo, alignment);

            vertexShaderConstantLocations.reserve(constantInfo.size());

            for (const ConstantInfo& info : vertexShaderConstantInfo)
            {
                GLint location = glGetUniformLocation(programId, info.name.c_str());

                if (location == -1)
                {
                    RendererOGL::checkOpenGLErrors();
                    return false;
                }

                vertexShaderConstantLocations.push_back(location);
            }

            return true;
        }

        bool ShaderOGL::setPixelShaderConstant(uint32_t index, uint32_t size, uint32_t count, const float* value)
        {
            if (index >= pixelShaderConstantLocations.size()) return false;

            RendererOGL::bindProgram(programId);

            GLint location = pixelShaderConstantLocations[index];

            uint32_t components = size / 4;

            switch (components)
            {
                case 1:
                    glUniform1fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 2:
                    glUniform2fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 3:
                    glUniform3fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 4:
                    glUniform4fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 9:
                    glUniformMatrix3fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                case 16:
                    glUniformMatrix4fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                default:
                    log("Unsupported uniform size");
                    return false;
            }

            return true;
        }

        bool ShaderOGL::setVertexShaderConstant(uint32_t index, uint32_t size, uint32_t count, const float* value)
        {
            if (index >= vertexShaderConstantLocations.size()) return false;

            RendererOGL::bindProgram(programId);

            GLint location = vertexShaderConstantLocations[index];

            uint32_t components = size / 4;

            switch (components)
            {
                case 1:
                    glUniform1fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 2:
                    glUniform2fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 3:
                    glUniform3fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 4:
                    glUniform4fv(location, static_cast<GLsizei>(count), value);
                    break;
                case 9:
                    glUniformMatrix3fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                case 16:
                    glUniformMatrix4fv(location, static_cast<GLsizei>(count), GL_FALSE, value);
                    break;
                default:
                    log("Unsupported uniform size");
                    return false;
            }

            return true;
        }
    } // namespace graphics
} // namespace ouzel
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP
#define STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP

#include <stan/math/prim/scal/meta/return_type.hpp>
#include <boost/math/special_functions/gamma.hpp>

namespace stan {

  namespace math {

    /**
     * Return the log of the binomial coefficient for the specified
     * arguments.
     *
     * The binomial coefficient, \f${N \choose n}\f$, read "N choose n", is
     * defined for \f$0 \leq n \leq N\f$ by
     *
     * \f${N \choose n} = \frac{N!}{n! (N-n)!}\f$.
     *
     * This function uses Gamma functions to define the log
     * and generalize the arguments to continuous N and n.
     *
     * \f$ \log {N \choose n} = \log \ \Gamma(N+1) - \log \Gamma(n+1) - \log \Gamma(N-n+1)\f$.
     *
     *
       \f[
       \mbox{binomial\_coefficient\_log}(x, y) =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \ln\Gamma(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\ln\Gamma(y+1)& \\
         \quad -\ln\Gamma(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial x} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \Psi(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial y} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         -\Psi(y+1) & \mbox{if } 0\leq y \leq x \\
         \quad +\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]
     *
     * @param N total number of objects.
     * @param n number of objects chosen.
     * @return log (N choose n).
     */
    template <typename T_N, typename T_n>
    inline typename return_type<T_N, T_n>::type
    binomial_coefficient_log(const T_N N, const T_n n) {
      using std::log;
      using boost::math::lgamma;

      const double cutoff = 1000;
      if ((N < cutoff) || (N - n < cutoff)) {
        return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
      } else {
        typename return_type<T_N, T_n>::type N_m_n(N - n);
        typename return_type<T_N, T_n>::type log_N_m_n(log(N_m_n));

        return n * log(N_m_n) + (N + 0.5) * (log(N) - log_N_m_n)
          + 1 / (12 * N) - n - 1 / (12 * N_m_n) - lgamma(n + 1.0);
      }
    }

  }
}
#endif
<commit_msg>Fixing the overpromotion<commit_after>#ifndef STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP
#define STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP

#include <stan/math/prim/scal/meta/return_type.hpp>
#include <boost/math/special_functions/gamma.hpp>

namespace stan {

  namespace math {

    /**
     * Return the log of the binomial coefficient for the specified
     * arguments.
     *
     * The binomial coefficient, \f${N \choose n}\f$, read "N choose n", is
     * defined for \f$0 \leq n \leq N\f$ by
     *
     * \f${N \choose n} = \frac{N!}{n! (N-n)!}\f$.
     *
     * This function uses Gamma functions to define the log
     * and generalize the arguments to continuous N and n.
     *
     * \f$ \log {N \choose n} = \log \ \Gamma(N+1) - \log \Gamma(n+1) - \log \Gamma(N-n+1)\f$.
     *
     *
       \f[
       \mbox{binomial\_coefficient\_log}(x, y) =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \ln\Gamma(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\ln\Gamma(y+1)& \\
         \quad -\ln\Gamma(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial x} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \Psi(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial y} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         -\Psi(y+1) & \mbox{if } 0\leq y \leq x \\
         \quad +\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]
     *
     * @param N total number of objects.
     * @param n number of objects chosen.
     * @return log (N choose n).
     */
    template <typename T_N, typename T_n>
    inline typename return_type<T_N, T_n>::type
    binomial_coefficient_log(const T_N N, const T_n n) {
      using std::log;
      using boost::math::lgamma;

      const double cutoff = 1000;
      if ((N < cutoff) || (N - n < cutoff)) {
        return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
      } else {
        return n * log(N - n) + (N + 0.5) * (log(N) - log(N - n))
          + 1 / (12 * N) - n - 1 / (12 * (N - n)) - lgamma(n + 1.0);
      }
    }

  }
}
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP
#define STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP

#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/tools/promotion.hpp>

namespace stan {

  namespace math {

    /**
     * Return the log of the binomial coefficient for the specified
     * arguments.
     *
     * The binomial coefficient, \f${N \choose n}\f$, read "N choose n", is
     * defined for \f$0 \leq n \leq N\f$ by
     *
     * \f${N \choose n} = \frac{N!}{n! (N-n)!}\f$.
     *
     * This function uses Gamma functions to define the log
     * and generalize the arguments to continuous N and n.
     *
     * \f$ \log {N \choose n} = \log \ \Gamma(N+1) - \log \Gamma(n+1) - \log \Gamma(N-n+1)\f$.
     *
     *
       \f[
       \mbox{binomial\_coefficient\_log}(x, y) =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \ln\Gamma(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\ln\Gamma(y+1)& \\
         \quad -\ln\Gamma(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial x} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \Psi(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial y} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         -\Psi(y+1) & \mbox{if } 0\leq y \leq x \\
         \quad +\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]
     *
     * @param N total number of objects.
     * @param n number of objects chosen.
     * @return log (N choose n).
     */
    template <typename T_N, typename T_n>
    inline typename boost::math::tools::promote_args<T_N, T_n>::type
    binomial_coefficient_log(const T_N N, const T_n n) {
      using std::log;
      using boost::math::lgamma;

      const double cutoff = 1000;
      if ((N < cutoff) || (N - n < cutoff)) {
        return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
      } else {
        return n * log(N - n) + (N + 0.5) * log(N/(N - n + 0.0))
          + 1.0 / (12 * N) - n - 1.0 / (12 * (N - n)) - lgamma(n + 1.0);
      }
    }

  }
}

#endif
<commit_msg>Adding template specialization for int<commit_after>#ifndef STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP
#define STAN_MATH_PRIM_SCAL_FUN_BINOMIAL_COEFFICIENT_LOG_HPP

#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/tools/promotion.hpp>

namespace stan {

  namespace math {

    /**
     * Return the log of the binomial coefficient for the specified
     * arguments.
     *
     * The binomial coefficient, \f${N \choose n}\f$, read "N choose n", is
     * defined for \f$0 \leq n \leq N\f$ by
     *
     * \f${N \choose n} = \frac{N!}{n! (N-n)!}\f$.
     *
     * This function uses Gamma functions to define the log
     * and generalize the arguments to continuous N and n.
     *
     * \f$ \log {N \choose n} = \log \ \Gamma(N+1) - \log \Gamma(n+1) - \log \Gamma(N-n+1)\f$.
     *
     *
       \f[
       \mbox{binomial\_coefficient\_log}(x, y) =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \ln\Gamma(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\ln\Gamma(y+1)& \\
         \quad -\ln\Gamma(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial x} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         \Psi(x+1) & \mbox{if } 0\leq y \leq x \\
         \quad -\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]

       \f[
       \frac{\partial\, \mbox{binomial\_coefficient\_log}(x, y)}{\partial y} =
       \begin{cases}
         \textrm{error} & \mbox{if } y > x \textrm{ or } y < 0\\
         -\Psi(y+1) & \mbox{if } 0\leq y \leq x \\
         \quad +\Psi(x-y+1)& \\[6pt]
         \textrm{NaN} & \mbox{if } x = \textrm{NaN or } y = \textrm{NaN}
       \end{cases}
       \f]
     *
     * @param N total number of objects.
     * @param n number of objects chosen.
     * @return log (N choose n).
     */
    template <typename T_N, typename T_n>
    inline typename boost::math::tools::promote_args<T_N, T_n>::type
    binomial_coefficient_log(const T_N N, const T_n n) {
      using std::log;
      using boost::math::lgamma;

      const double cutoff = 1000;
      if ((N < cutoff) || (N - n < cutoff)) {
        return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
      } else {
        return n * log(N - n) + (N + 0.5) * log(N / (N - n))
          + 1 / (12 * N) - n - 1 / (12 * (N - n)) - lgamma(n + 1.0);
      }
    }

    template <>
    inline double
    binomial_coefficient_log<int, int>(const int N, const int n) {
      using std::log;
      using boost::math::lgamma;

      const double cutoff = 1000;
      if ((N < cutoff) || (N - n < cutoff)) {
        return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
      } else {
        return n * log(N - n) + (N + 0.5) * log(N / static_cast<double>(N - n))
          + 1 / (12 * N) - n - 1 / (12 * (N - n)) - lgamma(n + 1.0);
      }
    }

  }
}

#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_CCDF_LOG_HPP
#define STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_CCDF_LOG_HPP

#include <boost/math/special_functions/digamma.hpp>
#include <boost/random/negative_binomial_distribution.hpp>
#include <boost/random/variate_generator.hpp>
#include <stan/math/prim/scal/meta/OperandsAndPartials.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_positive_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_less.hpp>
#include <stan/math/prim/scal/fun/constants.hpp>
#include <stan/math/prim/scal/fun/binomial_coefficient_log.hpp>
#include <stan/math/prim/scal/fun/multiply_log.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/meta/include_summand.hpp>
#include <stan/math/prim/scal/prob/neg_binomial_ccdf_log.hpp>
#include <stan/math/prim/scal/fun/grad_reg_inc_beta.hpp>
#include <stan/math/prim/scal/meta/VectorBuilder.hpp>
#include <vector>

namespace stan {

  namespace math {

    // Temporary neg_binomial_2_ccdf implementation that
    // transforms the input parameters and calls neg_binomial_ccdf
    template <typename T_n, typename T_location, typename T_precision>
    typename return_type<T_location, T_precision>::type
    neg_binomial_2_ccdf_log(const T_n& n,
                            const T_location& mu,
                            const T_precision& phi) {
      if ( !( stan::length(n) && stan::length(mu) && stan::length(phi) ) )
        return 0.0;

      using stan::math::check_nonnegative;
      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;
      using stan::math::check_less;

      static const char* function("stan::math::neg_binomial_2_cdf");
      check_positive_finite(function, "Location parameter", mu);
      check_positive_finite(function, "Precision parameter", phi);
      check_not_nan(function, "Random variable", n);
      check_consistent_sizes(function,
                             "Random variable", n,
                             "Location parameter", mu,
                             "Precision Parameter", phi);

      VectorView<const T_n> n_vec(n);
      VectorView<const T_location> mu_vec(mu);
      VectorView<const T_precision> phi_vec(phi);

      size_t size_beta = max_size(mu, phi);

      std::vector<typename return_type<T_location, T_precision>::type>
        beta_vec(size_beta);
      for (size_t i = 0; i < size_beta; ++i)
        beta_vec[i] = phi_vec[i] / mu_vec[i];

      // Cast a vector of size 1 down to a
      // scalar to avoid dimension mismatch
      if (size_beta == 1)
        return neg_binomial_ccdf_log(n, phi, beta_vec[0]);
      else
        return neg_binomial_ccdf_log(n, phi, beta_vec);
    }
  }
}
#endif
<commit_msg>Untangling more includes<commit_after>#ifndef STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_CCDF_LOG_HPP
#define STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_CCDF_LOG_HPP

#include <boost/math/special_functions/digamma.hpp>
#include <boost/random/negative_binomial_distribution.hpp>
#include <boost/random/variate_generator.hpp>
#include <stan/math/prim/scal/meta/OperandsAndPartials.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_positive_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_less.hpp>
#include <stan/math/prim/scal/fun/constants.hpp>
#include <stan/math/prim/scal/fun/binomial_coefficient_log.hpp>
#include <stan/math/prim/scal/fun/multiply_log.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/meta/include_summand.hpp>
#include <stan/math/prim/scal/prob/neg_binomial_ccdf_log.hpp>
#include <stan/math/prim/scal/fun/grad_reg_inc_beta.hpp>
#include <stan/math/prim/scal/meta/VectorBuilder.hpp>

namespace stan {

  namespace math {

    // Temporary neg_binomial_2_ccdf implementation that
    // transforms the input parameters and calls neg_binomial_ccdf
    template <typename T_n, typename T_location, typename T_precision>
    typename return_type<T_location, T_precision>::type
    neg_binomial_2_ccdf_log(const T_n& n,
                            const T_location& mu,
                            const T_precision& phi) {
      if ( !( stan::length(n) && stan::length(mu) && stan::length(phi) ) )
        return 0.0;

      using stan::math::check_nonnegative;
      using stan::math::check_positive_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;
      using stan::math::check_less;

      static const char* function("stan::math::neg_binomial_2_cdf");
      check_positive_finite(function, "Location parameter", mu);
      check_positive_finite(function, "Precision parameter", phi);
      check_not_nan(function, "Random variable", n);
      check_consistent_sizes(function,
                             "Random variable", n,
                             "Location parameter", mu,
                             "Precision Parameter", phi);

      VectorView<const T_n> n_vec(n);
      VectorView<const T_location> mu_vec(mu);
      VectorView<const T_precision> phi_vec(phi);

      size_t size_beta = max_size(mu, phi);

      VectorBuilder<true, typename return_type<T_location, T_precision>::type,
                    T_location, T_precision> beta_vec(size_beta);
      for (size_t i = 0; i < size_beta; ++i)
        beta_vec[i] = phi_vec[i] / mu_vec[i];

      return neg_binomial_ccdf_log(n, phi, beta_vec.get());
    }
  }
}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 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_frame/ready_mode/internal/ready_prompt_window.h"

#include <atlctrls.h>
#include <Shellapi.h>  // Must appear before atlctrlx.h

// These seem to be required by atlctrlx?
template<class A>
A min(A const& a, A const& b) { return a < b ? a : b; }

template<class A>
A max(A const& a, A const& b) { return a > b ? a : b; }

#include <atlctrlx.h>

#include "base/compiler_specific.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/ready_mode/internal/ready_mode_state.h"
#include "chrome_frame/ready_mode/internal/url_launcher.h"
#include "chrome_frame/simple_resource_loader.h"
#include "grit/chromium_strings.h"

ReadyPromptWindow::ReadyPromptWindow(
    InfobarContent::Frame* frame, ReadyModeState* ready_mode_state,
    UrlLauncher* url_launcher)
    : frame_(frame),
      ready_mode_state_(ready_mode_state),
      url_launcher_(url_launcher),
      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
ReadyPromptWindow::~ReadyPromptWindow() {
}

base::WeakPtr<ReadyPromptWindow> ReadyPromptWindow::CreateInstance(
    InfobarContent::Frame* frame, ReadyModeState* ready_mode_state,
    UrlLauncher* url_launcher) {
  DCHECK(frame != NULL);
  DCHECK(ready_mode_state != NULL);
  DCHECK(url_launcher != NULL);

  base::WeakPtr<ReadyPromptWindow> instance((new ReadyPromptWindow(
      frame, ready_mode_state, url_launcher))->weak_ptr_factory_.GetWeakPtr());

  DCHECK(!instance->IsWindow());

  if (instance->Create(frame->GetFrameWindow()) == NULL) {
    DPLOG(ERROR) << "Failed to create HWND for ReadyPromptWindow.";
    return base::WeakPtr<ReadyPromptWindow>();
  }

  // Subclass the "Learn more." text to make it behave like a link. Clicks are
  // routed to OnLearnMore().
  CWindow rte = instance->GetDlgItem(IDC_PROMPT_LINK);
  instance->link_.reset(new CHyperLink());
  instance->link_->SubclassWindow(rte);
  instance->link_->SetHyperLinkExtendedStyle(HLINK_NOTIFYBUTTON,
                                             HLINK_NOTIFYBUTTON);

  return instance;
}

void ReadyPromptWindow::OnDestroy() {
  frame_ = NULL;
}

BOOL ReadyPromptWindow::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) {
  DlgResize_Init(false);  // false => 'no gripper'
  return TRUE;
}

LRESULT ReadyPromptWindow::OnYes(WORD /*wNotifyCode*/,
                                 WORD /*wID*/,
                                 HWND /*hWndCtl*/,
                                 BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->AcceptChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnRemindMeLater(WORD /*wNotifyCode*/,
                                           WORD /*wID*/,
                                           HWND /*hWndCtl*/,
                                           BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->TemporarilyDeclineChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnNo(WORD /*wNotifyCode*/,
                                WORD /*wID*/,
                                HWND /*hWndCtl*/,
                                BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->PermanentlyDeclineChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnLearnMore(WORD /*wParam*/,
                                       LPNMHDR /*lParam*/,
                                       BOOL& /*bHandled*/) {
  url_launcher_->LaunchUrl(SimpleResourceLoader::Get(
      IDS_CHROME_FRAME_READY_MODE_LEARN_MORE_URL));
  return 0;
}

void ReadyPromptWindow::OnFinalMessage(HWND) {
  delete this;
}
<commit_msg>Replace one unfortunate hack with a somewhat better one. The included atlctrlx.h relies on min and max macros, which are generally bad and especially so in combination with STL.<commit_after>// Copyright (c) 2010 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_frame/ready_mode/internal/ready_prompt_window.h"

#include <atlctrls.h>
#include <Shellapi.h>

#include "base/compiler_specific.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/ready_mode/internal/ready_mode_state.h"
#include "chrome_frame/ready_mode/internal/url_launcher.h"
#include "chrome_frame/simple_resource_loader.h"
#include "grit/chromium_strings.h"

// atlctrlx.h requires 'min' and 'max' macros, the definition of which conflicts
// with STL headers. Hence we include them out of the order defined by style
// guidelines. As a result you may not refer to std::min or std::max in this
// file.
#include <minmax.h>  // NOLINT
#include <atlctrlx.h>  // NOLINT

ReadyPromptWindow::ReadyPromptWindow(
    InfobarContent::Frame* frame, ReadyModeState* ready_mode_state,
    UrlLauncher* url_launcher)
    : frame_(frame),
      ready_mode_state_(ready_mode_state),
      url_launcher_(url_launcher),
      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
ReadyPromptWindow::~ReadyPromptWindow() {
}

base::WeakPtr<ReadyPromptWindow> ReadyPromptWindow::CreateInstance(
    InfobarContent::Frame* frame, ReadyModeState* ready_mode_state,
    UrlLauncher* url_launcher) {
  DCHECK(frame != NULL);
  DCHECK(ready_mode_state != NULL);
  DCHECK(url_launcher != NULL);

  base::WeakPtr<ReadyPromptWindow> instance((new ReadyPromptWindow(
      frame, ready_mode_state, url_launcher))->weak_ptr_factory_.GetWeakPtr());

  DCHECK(!instance->IsWindow());

  if (instance->Create(frame->GetFrameWindow()) == NULL) {
    DPLOG(ERROR) << "Failed to create HWND for ReadyPromptWindow.";
    return base::WeakPtr<ReadyPromptWindow>();
  }

  // Subclass the "Learn more." text to make it behave like a link. Clicks are
  // routed to OnLearnMore().
  CWindow rte = instance->GetDlgItem(IDC_PROMPT_LINK);
  instance->link_.reset(new CHyperLink());
  instance->link_->SubclassWindow(rte);
  instance->link_->SetHyperLinkExtendedStyle(HLINK_NOTIFYBUTTON,
                                             HLINK_NOTIFYBUTTON);

  return instance;
}

void ReadyPromptWindow::OnDestroy() {
  frame_ = NULL;
}

BOOL ReadyPromptWindow::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) {
  DlgResize_Init(false);  // false => 'no gripper'
  return TRUE;
}

LRESULT ReadyPromptWindow::OnYes(WORD /*wNotifyCode*/,
                                 WORD /*wID*/,
                                 HWND /*hWndCtl*/,
                                 BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->AcceptChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnRemindMeLater(WORD /*wNotifyCode*/,
                                           WORD /*wID*/,
                                           HWND /*hWndCtl*/,
                                           BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->TemporarilyDeclineChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnNo(WORD /*wNotifyCode*/,
                                WORD /*wID*/,
                                HWND /*hWndCtl*/,
                                BOOL& /*bHandled*/) {
  frame_->CloseInfobar();
  ready_mode_state_->PermanentlyDeclineChromeFrame();
  return 0;
}

LRESULT ReadyPromptWindow::OnLearnMore(WORD /*wParam*/,
                                       LPNMHDR /*lParam*/,
                                       BOOL& /*bHandled*/) {
  url_launcher_->LaunchUrl(SimpleResourceLoader::Get(
      IDS_CHROME_FRAME_READY_MODE_LEARN_MORE_URL));
  return 0;
}

void ReadyPromptWindow::OnFinalMessage(HWND) {
  delete this;
}
<|endoftext|>