<commit_before>/*
 * Copyright (c) , Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 <ctype.h>
#include "nsapi_types.h"
#include "ATHandler.h"
#include "EventQueue.h"
#include "ATHandler_stub.h"

using namespace mbed;
using namespace events;

#include "CellularLog.h"

const int DEFAULT_AT_TIMEOUT = 1000; // at default timeout in milliseconds

nsapi_error_t ATHandler_stub::nsapi_error_value = 0;
uint8_t ATHandler_stub::nsapi_error_ok_counter = 0;
int ATHandler_stub::int_value = -1;
int ATHandler_stub::ref_count = 0;
int ATHandler_stub::timeout = 0;
bool ATHandler_stub::default_timeout = 0;
bool ATHandler_stub::debug_on = 0;
ssize_t ATHandler_stub::ssize_value = 0;
const char *ATHandler_stub::read_string_value = NULL;
size_t ATHandler_stub::size_value = 0;
size_t ATHandler_stub::return_given_size = false;
bool ATHandler_stub::bool_value = false;
uint8_t ATHandler_stub::uint8_value = 0;
FileHandle_stub *ATHandler_stub::fh_value = NULL;
device_err_t ATHandler_stub::device_err_value;
bool ATHandler_stub::call_immediately = false;
uint8_t ATHandler_stub::resp_info_true_counter = false;
uint8_t ATHandler_stub::info_elem_true_counter = false;
int ATHandler_stub::int_valid_count_table[kRead_int_table_size];
int ATHandler_stub::int_count = kRead_int_table_size;
bool ATHandler_stub::process_oob_urc = false;

int ATHandler_stub::read_string_index = kRead_string_table_size;
const char *ATHandler_stub::read_string_table[kRead_string_table_size];
int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
int ATHandler_stub::urc_amount = 0;
mbed::Callback<void()> ATHandler_stub::callback[kATHandler_urc_table_max_size];
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size];

ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
    _nextATHandler(0),
    _fileHandle(fh),
    _queue(queue)
{
    ATHandler_stub::ref_count = 1;

    ATHandler_stub::process_oob_urc = false;
    ATHandler_stub::urc_amount = 0;
    int i=0;
    while (i < kATHandler_urc_table_max_size) {
        ATHandler_stub::callback[i] = NULL;
        ATHandler_stub::urc_string_table[i++] = NULL;
    }
}

void ATHandler::set_debug(bool debug_on)
{
    ATHandler_stub::debug_on = debug_on;
}

ATHandler::~ATHandler()
{
    ATHandler_stub::ref_count = kATHandler_destructor_ref_ount;

    int i=0;
    while (i < kATHandler_urc_table_max_size) {
        if (ATHandler_stub::urc_string_table[i]) {
            delete [] ATHandler_stub::urc_string_table[i];
            i++;
        } else {
            break;
        }
    }
}

void ATHandler::inc_ref_count()
{
    ATHandler_stub::ref_count++;
}

void ATHandler::dec_ref_count()
{
    ATHandler_stub::ref_count--;
}

int ATHandler::get_ref_count()
{
    return ATHandler_stub::ref_count;
}

FileHandle *ATHandler::get_file_handle()
{
    return ATHandler_stub::fh_value;
}

void ATHandler::set_file_handle(FileHandle *fh)
{
}

nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
{
    if (ATHandler_stub::urc_amount < kATHandler_urc_table_max_size) {
        ATHandler_stub::callback[ATHandler_stub::urc_amount] = cb;
        ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount] = new char[kATHandler_urc_string_max_size];
        if (urc) {
            int bytes_to_copy = strlen(urc) < kATHandler_urc_string_max_size ? strlen(urc) : kATHandler_urc_string_max_size;
            memcpy(ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount], urc, bytes_to_copy);
        }
        ATHandler_stub::urc_amount++;
    } else {
        ATHandler_stub::callback[0] = cb;
        MBED_ASSERT("ATHandler URC amount limit reached");
    }
    if (ATHandler_stub::call_immediately) {
        cb();
    }
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::remove_urc_handler(const char *prefix)
{
}

nsapi_error_t ATHandler::get_last_error() const
{
    if (ATHandler_stub::nsapi_error_ok_counter) {
        ATHandler_stub::nsapi_error_ok_counter--;
        return NSAPI_ERROR_OK;
    }
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::lock()
{
}

void ATHandler::unlock()
{
}

nsapi_error_t ATHandler::unlock_return_error()
{
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout)
{
    ATHandler_stub::timeout = timeout_milliseconds;
    ATHandler_stub::default_timeout = default_timeout;
}

void ATHandler::restore_at_timeout()
{
}

void ATHandler::process_oob()
{
    if (ATHandler_stub::process_oob_urc) {
        int i = 0;
        while (i < ATHandler_stub::urc_amount) {
            if (ATHandler_stub::read_string_index >= 0) {
                if (!memcmp(ATHandler_stub::urc_string_table[i],
                    ATHandler_stub::read_string_table[ATHandler_stub::read_string_index],
                    strlen(ATHandler_stub::urc_string_table[i]))) {
                        ATHandler_stub::callback[i]();
                        break;
                }
            }
            i++;
        }
    }
}

void ATHandler::clear_error()
{
    ATHandler_stub::nsapi_error_ok_counter++;
}

void ATHandler::skip_param(uint32_t count)
{

}

void ATHandler::skip_param(ssize_t len, uint32_t count)
{
}

ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
{
    return ATHandler_stub::ssize_value;
}

ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
{

    if (ATHandler_stub::read_string_index == kRead_string_table_size) {
        if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) {
            memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value + 1);
            buf[ATHandler_stub::ssize_value] = '\0';
        }
        return ATHandler_stub::ssize_value;
    }

    ATHandler_stub::read_string_index--;
    if (ATHandler_stub::read_string_index >= 0) {
        const char *tmp = ATHandler_stub::read_string_table[ATHandler_stub::read_string_index];
        ssize_t len = strlen(tmp);
        memcpy(buf, tmp, len + 1);
        buf[len] = '\0';
        return len;
    }

    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
    return -1;
}

int32_t ATHandler::read_int()
{
    if (ATHandler_stub::nsapi_error_value != NSAPI_ERROR_OK) {
        return -1;
    }

    if (ATHandler_stub::int_count == kRead_int_table_size) {
        return ATHandler_stub::int_value;
    }

    //printf("ATHandler_stub::int_count: %d", ATHandler_stub::int_count);
    ATHandler_stub::int_count--;
    if (ATHandler_stub::int_count < kRead_int_table_size && ATHandler_stub::int_count >= 0) {
        return ATHandler_stub::int_valid_count_table[ATHandler_stub::int_count];
    }

    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
    return -1;
}

void ATHandler::set_delimiter(char delimiter)
{
}

void ATHandler::set_default_delimiter()
{
}

void ATHandler::set_stop_tag(const char *stop_tag_seq)
{
}

int ATHandler::get_3gpp_error()
{
    return ATHandler_stub::int_value;
}

void ATHandler::resp_start(const char *prefix, bool stop)
{
}

bool ATHandler::info_resp()
{
    if (ATHandler_stub::resp_info_true_counter) {
        ATHandler_stub::resp_info_true_counter--;
        return true;
    }
    return ATHandler_stub::bool_value;
}

bool ATHandler::info_elem(char start_tag)
{
    if (ATHandler_stub::info_elem_true_counter) {
        ATHandler_stub::info_elem_true_counter--;
        return true;
    }
    return ATHandler_stub::bool_value;
}

bool ATHandler::consume_to_stop_tag()
{
    return ATHandler_stub::bool_value;
}

void ATHandler::resp_stop()
{
    if (ATHandler_stub::resp_stop_success_count > 0) {
        ATHandler_stub::resp_stop_success_count--;
        return;
    }
    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
}

void ATHandler::cmd_start(const char *cmd)
{
}

void ATHandler::write_int(int32_t param)
{
}

void ATHandler::write_string(const char *param, bool useQuotations)
{
}

size_t ATHandler::write_bytes(const uint8_t *param, size_t len)
{
    if (ATHandler_stub::return_given_size) {
        return len;
    }
    return ATHandler_stub::size_value;
}

void ATHandler::cmd_stop()
{
}

void ATHandler::cmd_stop_read_resp()
{
    cmd_stop();
    resp_start();
    resp_stop();
}

device_err_t ATHandler::get_last_device_error() const
{
    return ATHandler_stub::device_err_value;
}

void ATHandler::flush()
{

}
<commit_msg>cellular: registration status change astyle fix<commit_after>/*
 * Copyright (c) , Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 <ctype.h>
#include "nsapi_types.h"
#include "ATHandler.h"
#include "EventQueue.h"
#include "ATHandler_stub.h"

using namespace mbed;
using namespace events;

#include "CellularLog.h"

const int DEFAULT_AT_TIMEOUT = 1000; // at default timeout in milliseconds

nsapi_error_t ATHandler_stub::nsapi_error_value = 0;
uint8_t ATHandler_stub::nsapi_error_ok_counter = 0;
int ATHandler_stub::int_value = -1;
int ATHandler_stub::ref_count = 0;
int ATHandler_stub::timeout = 0;
bool ATHandler_stub::default_timeout = 0;
bool ATHandler_stub::debug_on = 0;
ssize_t ATHandler_stub::ssize_value = 0;
const char *ATHandler_stub::read_string_value = NULL;
size_t ATHandler_stub::size_value = 0;
size_t ATHandler_stub::return_given_size = false;
bool ATHandler_stub::bool_value = false;
uint8_t ATHandler_stub::uint8_value = 0;
FileHandle_stub *ATHandler_stub::fh_value = NULL;
device_err_t ATHandler_stub::device_err_value;
bool ATHandler_stub::call_immediately = false;
uint8_t ATHandler_stub::resp_info_true_counter = false;
uint8_t ATHandler_stub::info_elem_true_counter = false;
int ATHandler_stub::int_valid_count_table[kRead_int_table_size];
int ATHandler_stub::int_count = kRead_int_table_size;
bool ATHandler_stub::process_oob_urc = false;

int ATHandler_stub::read_string_index = kRead_string_table_size;
const char *ATHandler_stub::read_string_table[kRead_string_table_size];
int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
int ATHandler_stub::urc_amount = 0;
mbed::Callback<void()> ATHandler_stub::callback[kATHandler_urc_table_max_size];
char *ATHandler_stub::urc_string_table[kATHandler_urc_table_max_size];

ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
    _nextATHandler(0),
    _fileHandle(fh),
    _queue(queue)
{
    ATHandler_stub::ref_count = 1;

    ATHandler_stub::process_oob_urc = false;
    ATHandler_stub::urc_amount = 0;
    int i = 0;
    while (i < kATHandler_urc_table_max_size) {
        ATHandler_stub::callback[i] = NULL;
        ATHandler_stub::urc_string_table[i++] = NULL;
    }
}

void ATHandler::set_debug(bool debug_on)
{
    ATHandler_stub::debug_on = debug_on;
}

ATHandler::~ATHandler()
{
    ATHandler_stub::ref_count = kATHandler_destructor_ref_ount;

    int i = 0;
    while (i < kATHandler_urc_table_max_size) {
        if (ATHandler_stub::urc_string_table[i]) {
            delete [] ATHandler_stub::urc_string_table[i];
            i++;
        } else {
            break;
        }
    }
}

void ATHandler::inc_ref_count()
{
    ATHandler_stub::ref_count++;
}

void ATHandler::dec_ref_count()
{
    ATHandler_stub::ref_count--;
}

int ATHandler::get_ref_count()
{
    return ATHandler_stub::ref_count;
}

FileHandle *ATHandler::get_file_handle()
{
    return ATHandler_stub::fh_value;
}

void ATHandler::set_file_handle(FileHandle *fh)
{
}

nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
{
    if (ATHandler_stub::urc_amount < kATHandler_urc_table_max_size) {
        ATHandler_stub::callback[ATHandler_stub::urc_amount] = cb;
        ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount] = new char[kATHandler_urc_string_max_size];
        if (urc) {
            int bytes_to_copy = strlen(urc) < kATHandler_urc_string_max_size ? strlen(urc) : kATHandler_urc_string_max_size;
            memcpy(ATHandler_stub::urc_string_table[ATHandler_stub::urc_amount], urc, bytes_to_copy);
        }
        ATHandler_stub::urc_amount++;
    } else {
        ATHandler_stub::callback[0] = cb;
        MBED_ASSERT("ATHandler URC amount limit reached");
    }
    if (ATHandler_stub::call_immediately) {
        cb();
    }
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::remove_urc_handler(const char *prefix)
{
}

nsapi_error_t ATHandler::get_last_error() const
{
    if (ATHandler_stub::nsapi_error_ok_counter) {
        ATHandler_stub::nsapi_error_ok_counter--;
        return NSAPI_ERROR_OK;
    }
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::lock()
{
}

void ATHandler::unlock()
{
}

nsapi_error_t ATHandler::unlock_return_error()
{
    return ATHandler_stub::nsapi_error_value;
}

void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout)
{
    ATHandler_stub::timeout = timeout_milliseconds;
    ATHandler_stub::default_timeout = default_timeout;
}

void ATHandler::restore_at_timeout()
{
}

void ATHandler::process_oob()
{
    if (ATHandler_stub::process_oob_urc) {
        int i = 0;
        while (i < ATHandler_stub::urc_amount) {
            if (ATHandler_stub::read_string_index >= 0) {
                if (!memcmp(ATHandler_stub::urc_string_table[i],
                            ATHandler_stub::read_string_table[ATHandler_stub::read_string_index],
                            strlen(ATHandler_stub::urc_string_table[i]))) {
                    ATHandler_stub::callback[i]();
                    break;
                }
            }
            i++;
        }
    }
}

void ATHandler::clear_error()
{
    ATHandler_stub::nsapi_error_ok_counter++;
}

void ATHandler::skip_param(uint32_t count)
{

}

void ATHandler::skip_param(ssize_t len, uint32_t count)
{
}

ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
{
    return ATHandler_stub::ssize_value;
}

ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
{

    if (ATHandler_stub::read_string_index == kRead_string_table_size) {
        if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) {
            memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value + 1);
            buf[ATHandler_stub::ssize_value] = '\0';
        }
        return ATHandler_stub::ssize_value;
    }

    ATHandler_stub::read_string_index--;
    if (ATHandler_stub::read_string_index >= 0) {
        const char *tmp = ATHandler_stub::read_string_table[ATHandler_stub::read_string_index];
        ssize_t len = strlen(tmp);
        memcpy(buf, tmp, len + 1);
        buf[len] = '\0';
        return len;
    }

    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
    return -1;
}

int32_t ATHandler::read_int()
{
    if (ATHandler_stub::nsapi_error_value != NSAPI_ERROR_OK) {
        return -1;
    }

    if (ATHandler_stub::int_count == kRead_int_table_size) {
        return ATHandler_stub::int_value;
    }

    //printf("ATHandler_stub::int_count: %d", ATHandler_stub::int_count);
    ATHandler_stub::int_count--;
    if (ATHandler_stub::int_count < kRead_int_table_size && ATHandler_stub::int_count >= 0) {
        return ATHandler_stub::int_valid_count_table[ATHandler_stub::int_count];
    }

    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
    return -1;
}

void ATHandler::set_delimiter(char delimiter)
{
}

void ATHandler::set_default_delimiter()
{
}

void ATHandler::set_stop_tag(const char *stop_tag_seq)
{
}

int ATHandler::get_3gpp_error()
{
    return ATHandler_stub::int_value;
}

void ATHandler::resp_start(const char *prefix, bool stop)
{
}

bool ATHandler::info_resp()
{
    if (ATHandler_stub::resp_info_true_counter) {
        ATHandler_stub::resp_info_true_counter--;
        return true;
    }
    return ATHandler_stub::bool_value;
}

bool ATHandler::info_elem(char start_tag)
{
    if (ATHandler_stub::info_elem_true_counter) {
        ATHandler_stub::info_elem_true_counter--;
        return true;
    }
    return ATHandler_stub::bool_value;
}

bool ATHandler::consume_to_stop_tag()
{
    return ATHandler_stub::bool_value;
}

void ATHandler::resp_stop()
{
    if (ATHandler_stub::resp_stop_success_count > 0) {
        ATHandler_stub::resp_stop_success_count--;
        return;
    }
    ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
}

void ATHandler::cmd_start(const char *cmd)
{
}

void ATHandler::write_int(int32_t param)
{
}

void ATHandler::write_string(const char *param, bool useQuotations)
{
}

size_t ATHandler::write_bytes(const uint8_t *param, size_t len)
{
    if (ATHandler_stub::return_given_size) {
        return len;
    }
    return ATHandler_stub::size_value;
}

void ATHandler::cmd_stop()
{
}

void ATHandler::cmd_stop_read_resp()
{
    cmd_stop();
    resp_start();
    resp_stop();
}

device_err_t ATHandler::get_last_device_error() const
{
    return ATHandler_stub::device_err_value;
}

void ATHandler::flush()
{

}
<|endoftext|>


<commit_before>#ifndef ITER_ACCUMULATE_H_
#define ITER_ACCUMULATE_H_

#include "internal/iterbase.hpp"

#include <utility>
#include <iterator>
#include <initializer_list>
#include <functional>
#include <type_traits>
#include <memory>

namespace iter {
  namespace impl {
    template <typename Container, typename AccumulateFunc>
    class Accumulator;
  }

  template <typename Container, typename AccumulateFunc>
  impl::Accumulator<Container, AccumulateFunc> accumulate(
      Container&&, AccumulateFunc);

  template <typename T, typename AccumulateFunc>
  impl::Accumulator<std::initializer_list<T>, AccumulateFunc> accumulate(
      std::initializer_list<T>, AccumulateFunc);
}

template <typename Container, typename AccumulateFunc>
class iter::impl::Accumulator {
 private:
  Container container;
  AccumulateFunc accumulate_func;

  friend Accumulator iter::accumulate<Container, AccumulateFunc>(
      Container&&, AccumulateFunc);

  template <typename T, typename AF>
  friend Accumulator<std::initializer_list<T>, AF> iter::accumulate(
      std::initializer_list<T>, AF);

  using AccumVal = std::remove_reference_t<std::result_of_t<AccumulateFunc(
      iterator_deref<Container>, iterator_deref<Container>)>>;

  Accumulator(Container&& in_container, AccumulateFunc in_accumulate_func)
      : container(std::forward<Container>(in_container)),
        accumulate_func(in_accumulate_func) {}

 public:
  Accumulator(Accumulator&&) = default;

  class Iterator : public std::iterator<std::input_iterator_tag, AccumVal> {
   private:
    iterator_type<Container> sub_iter;
    iterator_type<Container> sub_end;
    AccumulateFunc* accumulate_func;
    std::unique_ptr<AccumVal> acc_val;

   public:
    Iterator(iterator_type<Container>&& iter, iterator_type<Container>&& end,
        AccumulateFunc& in_accumulate_fun)
        : sub_iter{std::move(iter)},
          sub_end{std::move(end)},
          accumulate_func(&in_accumulate_fun),
          // only get first value if not an end iterator
          acc_val{!(iter != end) ? nullptr : new AccumVal(*iter)} {}

    Iterator(const Iterator& other)
        : sub_iter{other.sub_iter},
          sub_end{other.sub_end},
          accumulate_func{other.accumulate_func},
          acc_val{other.acc_val ? new AccumVal(*other.acc_val) : nullptr} {}

    Iterator& operator=(const Iterator& other) {
      if (this == &other) { return *this; }
      this->sub_iter = other.sub_iter;
      this->sub_end = other.sub_end;
      this->accumulate_func = other.accumulate_func;
      this->acc_val.reset(
          other.acc_val ? new AccumVal(*other.acc_val) : nullptr);
      return *this;
    }

    Iterator(Iterator&&) = default;
    Iterator& operator=(Iterator&&) = default;

    const AccumVal& operator*() const {
      return *this->acc_val;
    }

    const AccumVal* operator->() const {
      return this->acc_val.get();
    }

    Iterator& operator++() {
      ++this->sub_iter;
      if (this->sub_iter != this->sub_end) {
        *this->acc_val = (*accumulate_func)(*this->acc_val, *this->sub_iter);
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(this->container), std::end(this->container),
        this->accumulate_func};
  }

  Iterator end() {
    return {std::end(this->container), std::end(this->container),
        this->accumulate_func};
  }
};

template <typename Container, typename AccumulateFunc>
iter::impl::Accumulator<Container, AccumulateFunc> iter::accumulate(
    Container&& container, AccumulateFunc accumulate_func) {
  return {std::forward<Container>(container), accumulate_func};
}

template <typename T, typename AccumulateFunc>
iter::impl::Accumulator<std::initializer_list<T>, AccumulateFunc>
iter::accumulate(std::initializer_list<T> il, AccumulateFunc accumulate_func) {
  return {std::move(il), accumulate_func};
}

namespace iter {
  template <typename Container>
  auto accumulate(Container&& container) -> decltype(accumulate(
      std::forward<Container>(container),
      std::plus<std::remove_reference_t<impl::iterator_deref<Container>>>{})) {
    return accumulate(std::forward<Container>(container),
        std::plus<std::remove_reference_t<impl::iterator_deref<Container>>>{});
  }

  template <typename T>
  auto accumulate(std::initializer_list<T> il)
      -> decltype(accumulate(std::move(il), std::plus<T>{})) {
    return accumulate(std::move(il), std::plus<T>{});
  }
}

#endif
<commit_msg>drops init list support from accumulate<commit_after>#ifndef ITER_ACCUMULATE_H_
#define ITER_ACCUMULATE_H_

#include "internal/iterbase.hpp"

#include <utility>
#include <iterator>
#include <functional>
#include <type_traits>
#include <memory>

namespace iter {
  namespace impl {
    template <typename Container, typename AccumulateFunc>
    class Accumulator;
  }

  template <typename Container, typename AccumulateFunc>
  impl::Accumulator<Container, AccumulateFunc> accumulate(
      Container&&, AccumulateFunc);

}

template <typename Container, typename AccumulateFunc>
class iter::impl::Accumulator {
 private:
  Container container;
  AccumulateFunc accumulate_func;

  friend Accumulator iter::accumulate<Container, AccumulateFunc>(
      Container&&, AccumulateFunc);

  using AccumVal = std::remove_reference_t<std::result_of_t<AccumulateFunc(
      iterator_deref<Container>, iterator_deref<Container>)>>;

  Accumulator(Container&& in_container, AccumulateFunc in_accumulate_func)
      : container(std::forward<Container>(in_container)),
        accumulate_func(in_accumulate_func) {}

 public:
  Accumulator(Accumulator&&) = default;

  class Iterator : public std::iterator<std::input_iterator_tag, AccumVal> {
   private:
    iterator_type<Container> sub_iter;
    iterator_type<Container> sub_end;
    AccumulateFunc* accumulate_func;
    std::unique_ptr<AccumVal> acc_val;

   public:
    Iterator(iterator_type<Container>&& iter, iterator_type<Container>&& end,
        AccumulateFunc& in_accumulate_fun)
        : sub_iter{std::move(iter)},
          sub_end{std::move(end)},
          accumulate_func(&in_accumulate_fun),
          // only get first value if not an end iterator
          acc_val{!(iter != end) ? nullptr : new AccumVal(*iter)} {}

    Iterator(const Iterator& other)
        : sub_iter{other.sub_iter},
          sub_end{other.sub_end},
          accumulate_func{other.accumulate_func},
          acc_val{other.acc_val ? new AccumVal(*other.acc_val) : nullptr} {}

    Iterator& operator=(const Iterator& other) {
      if (this == &other) { return *this; }
      this->sub_iter = other.sub_iter;
      this->sub_end = other.sub_end;
      this->accumulate_func = other.accumulate_func;
      this->acc_val.reset(
          other.acc_val ? new AccumVal(*other.acc_val) : nullptr);
      return *this;
    }

    Iterator(Iterator&&) = default;
    Iterator& operator=(Iterator&&) = default;

    const AccumVal& operator*() const {
      return *this->acc_val;
    }

    const AccumVal* operator->() const {
      return this->acc_val.get();
    }

    Iterator& operator++() {
      ++this->sub_iter;
      if (this->sub_iter != this->sub_end) {
        *this->acc_val = (*accumulate_func)(*this->acc_val, *this->sub_iter);
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(this->container), std::end(this->container),
        this->accumulate_func};
  }

  Iterator end() {
    return {std::end(this->container), std::end(this->container),
        this->accumulate_func};
  }
};

template <typename Container, typename AccumulateFunc>
iter::impl::Accumulator<Container, AccumulateFunc> iter::accumulate(
    Container&& container, AccumulateFunc accumulate_func) {
  return {std::forward<Container>(container), accumulate_func};
}

namespace iter {
  template <typename Container>
  auto accumulate(Container&& container) -> decltype(accumulate(
      std::forward<Container>(container),
      std::plus<std::remove_reference_t<impl::iterator_deref<Container>>>{})) {
    return accumulate(std::forward<Container>(container),
        std::plus<std::remove_reference_t<impl::iterator_deref<Container>>>{});
  }
}

#endif
<|endoftext|>


<commit_before>//MIT License
//Copyright(c) 2017 Patrick Laughrea
#include "parser.h"

//#define DISABLE_IMPORT
#ifndef DISABLE_IMPORT
#include "curl.h"
#endif
#include "errors.h"
#include "patternsContainers.h"
#include "WebssonUtils/constants.h"
#include "WebssonUtils/utilsWebss.h"

using namespace std;
using namespace webss;

const char ERROR_INPUT_DICTIONARY[] = "dictionary can only have key-values";
const char ERROR_INPUT_LIST[] = "list can only have concrete value-onlys";
const char ERROR_INPUT_TUPLE[] = "tuple can only have concrete value-onlys or key-values";
const char ERROR_INPUT_NAMESPACE[] = "namespace can only have entity definitions";
const char ERROR_INPUT_ENUM[] = "enum can only have key-onlys";
const char ERROR_INPUT_DOCUMENT[] = "document can only have concrete value-onlys or key-values";

string getItPosition(SmartIterator& it)
{
	return "[ln " + to_string(it.getLine()) + ", ch " + to_string(it.getCharCount()) + "]";
}

string getItCurrentChar(SmartIterator& it)
{
	if (!it)
		return string("");

	string out;
	out += " '";
	if (*it == '\'' || *it == '\\')
		out += '\\';
	out = out + *it + "' ";

	switch (*it)
	{
	case '~': out += "(using namespace)"; break;
	case '!': out += "(entity declaration)"; break;
	case '@': out += "(import)"; break;
	case '#': out += "(option)"; break;
	case '&': out += "(self)"; break;
	case ':': out += "(line string)"; break;
	case '"': out += "(cstring)"; break;
	case '?': out += "(entity declaration)"; break;
	case '.': out += "(scope)"; break;
	case '(': case ')':out += "(parenthesis / round bracket)"; break;
	case '{': case '}': out += "(brace / curly bracket)"; break;
	case '[': case ']': out += "(square bracket)"; break;
	case '<': case '>': out += "(angle bracket / chevron)"; break;
	default:
		break;
	}
	return out;
}

Dictionary Parser::parseDictionary()
{
	return parseContainer<Dictionary, ConType::DICTIONARY>(Dictionary(), [&](Dictionary& dict)
	{
		if (nextTag == Tag::C_STRING)
			addJsonKeyvalue(dict);
		else
			parseOtherValue(
				CaseKeyValue{ dict.addSafe(move(key), move(value)); },
				ErrorKeyOnly(ERROR_INPUT_DICTIONARY),
				ErrorValueOnly(ERROR_INPUT_DICTIONARY),
				ErrorAbstractEntity(ERROR_INPUT_DICTIONARY));
	});
}

List Parser::parseList()
{
	return parseContainer<List, ConType::LIST>(List(), [&](List& list)
	{
		list.add(parseValueOnly());
	});
}

Tuple Parser::parseTuple()
{
	return parseContainer<Tuple, ConType::TUPLE>(Tuple(), [&](Tuple& tuple)
	{
		parseOtherValue(
			CaseKeyValue{ tuple.addSafe(move(key), move(value)); },
			ErrorKeyOnly(ERROR_INPUT_TUPLE),
			CaseValueOnly{ tuple.add(move(value)); },
			ErrorAbstractEntity(ERROR_INPUT_TUPLE));
	});
}

List Parser::parseListText()
{
	return parseContainer<List, ConType::LIST>(List(), [&](List& list)
	{
		list.add(parseLineString());
	});
}
Tuple Parser::parseTupleText()
{
	return parseContainer<Tuple, ConType::TUPLE>(Tuple(), [&](Tuple& tuple)
	{
		tuple.add(parseLineString());
	});
}

Namespace Parser::parseNamespace(const string& name, const Namespace& previousNamespace)
{
	return parseContainer<Namespace, ConType::DICTIONARY>(Namespace(name, previousNamespace), [&](Namespace& nspace)
	{
		switch (*it)
		{
		case CHAR_ABSTRACT_ENTITY:
			++it;
			nspace.addSafe(parseAbstractEntity(nspace));
			break;
		case CHAR_CONCRETE_ENTITY:
			++it;
			nspace.addSafe(parseConcreteEntity());
			break;
		case CHAR_SELF:
			skipJunkToTag(++it, Tag::START_TEMPLATE);
			nspace.addSafe(Entity(string(name), parseTemplateHead()));
			break;
		default:
			throw runtime_error(ERROR_INPUT_NAMESPACE);
		}
	});
}

Enum Parser::parseEnum(const string& name)
{
	return parseContainer<Enum, ConType::LIST>(Enum(name), [&](Enum& tEnum)
	{
		parseOtherValue(
			ErrorKeyValue(ERROR_INPUT_ENUM),
			CaseKeyOnly{ tEnum.add(move(key)); },
			ErrorValueOnly(ERROR_INPUT_ENUM),
			ErrorAbstractEntity(ERROR_INPUT_ENUM));
	});
}

Document Parser::parseDocument()
{
	try
	{
		Document doc;
		if (!containerEmpty() && !parseDocumentHead(doc.getHead(), Namespace::getEmptyInstance()))
		{
			do
				parseOtherValue(
					CaseKeyValue{ doc.addSafe(move(key), move(value)); },
					ErrorKeyOnly(ERROR_INPUT_DOCUMENT),
					CaseValueOnly{ doc.add(move(value)); },
					ErrorAbstractEntity(ERROR_INPUT_DOCUMENT));
			while (checkNextElement());
		}
		return doc;
	}
	catch (const exception& e)
	{
		throw runtime_error(string(getItPosition(it) + ' ' + e.what() + getItCurrentChar(it)).c_str());
	}
}

bool Parser::parseDocumentHead(vector<ParamDocument>& docHead, const Namespace& nspace)
{
	assert(it);
	do
	{
		switch (*it)
		{
		case CHAR_ABSTRACT_ENTITY:
		{
			++it;
			auto ent = parseAbstractEntity(nspace);
			docHead.push_back(ParamDocument::makeEntityAbstract(ent));
			ents.addLocalSafe(move(ent));
			break;
		}
		case CHAR_CONCRETE_ENTITY:
		{
			++it;
			auto ent = parseConcreteEntity();
			docHead.push_back(ParamDocument::makeEntityConcrete(ent));
			ents.addLocalSafe(move(ent));
			break;
		}
		case CHAR_IMPORT:
		{
			++it;
			auto import = parseImport();
			docHead.push_back(move(import));
			break;
		}
		case CHAR_SCOPED_DOCUMENT:
			++it;
			parseScopedDocument(docHead);
			break;
		default:
			return false;
		}
	} while (checkNextElement());
	return true;
}

void Parser::parseScopedDocument(vector<ParamDocument>& docHead)
{
	if (*skipJunkToValid(it) == OPEN_TEMPLATE)
	{
		ContainerSwitcher switcher1(*this, ConType::TEMPLATE_HEAD, false);
		if (containerEmpty())
			throw runtime_error("can't have empty scoped document head");

		auto head = parseTemplateHeadScoped();

		skipJunkToTag(it, Tag::START_DICTIONARY);
		DocumentHead body;

		ContainerSwitcher switcher2(*this, ConType::DICTIONARY, false);
		if (!containerEmpty())
		{
			ParamDocumentIncluder includer(ents, head.getParameters());
			if (!parseDocumentHead(body, Namespace::getEmptyInstance()))
				throw runtime_error(ERROR_UNEXPECTED);
		}
		docHead.push_back(ScopedDocument{ move(head), move(body) });
	}
	else
	{
		const auto& nspace = parseUsingNamespaceStatic();

		//first check the namespace entity is accessible; if so it has to be removed since
		//it'll no longer be necessary and an entity with the same name could be inside
		if (ParamDocumentIncluder::namespacePresentScope(ents, nspace))
			ents.removeLocal(ents[nspace.getName()]);

		for (const auto& ent : nspace)
			ents.addLocalSafe(ent);
	}
}

ImportedDocument Parser::parseImport()
{
#ifdef DISABLE_IMPORT
	throw runtime_error("this parser cannot import documents");
#else
	nextTag = getTag(it);
	auto importName = parseValueOnly();
	if (!importName.isString())
		throw runtime_error("import must reference a string");
	ImportedDocument import(move(importName));
	const auto& link = import.getLink();
	if (!importedDocuments.hasEntity(link))
	{
		try
		{
			importedDocuments.addLocalSafe(link, 0);
			ImportSwitcher switcher(*this, SmartIterator(Curl().readWebDocument(link)));
			DocumentHead docHead;
			if (!containerEmpty() && !parseDocumentHead(docHead, Namespace::getEmptyInstance()))
				throw runtime_error(ERROR_UNEXPECTED);
		}
		catch (const exception& e)
			{ throw runtime_error(string("while parsing import, ") + e.what()); }
	}
	return import;
#endif
}

const Namespace& Parser::parseUsingNamespaceStatic()
{
	skipJunkToTag(it, Tag::NAME_START);
	auto nameType = parseNameType();
	if (nameType.type != NameType::ENTITY_ABSTRACT || !nameType.entity.getContent().isNamespace())
		throw runtime_error("expected namespace");
	return nameType.entity.getContent().getNamespaceSafe();
}<commit_msg>Scoped names for namespace and enum<commit_after>//MIT License
//Copyright(c) 2017 Patrick Laughrea
#include "parser.h"

//#define DISABLE_IMPORT
#ifndef DISABLE_IMPORT
#include "curl.h"
#endif
#include "errors.h"
#include "patternsContainers.h"
#include "WebssonUtils/constants.h"
#include "WebssonUtils/utilsWebss.h"

using namespace std;
using namespace webss;

const char ERROR_INPUT_DICTIONARY[] = "dictionary can only have key-values";
const char ERROR_INPUT_LIST[] = "list can only have concrete value-onlys";
const char ERROR_INPUT_TUPLE[] = "tuple can only have concrete value-onlys or key-values";
const char ERROR_INPUT_NAMESPACE[] = "namespace can only have entity definitions";
const char ERROR_INPUT_ENUM[] = "enum can only have key-onlys";
const char ERROR_INPUT_DOCUMENT[] = "document can only have concrete value-onlys or key-values";

string getItPosition(SmartIterator& it)
{
	return "[ln " + to_string(it.getLine()) + ", ch " + to_string(it.getCharCount()) + "]";
}

string getItCurrentChar(SmartIterator& it)
{
	if (!it)
		return string("");

	string out;
	out += " '";
	if (*it == '\'' || *it == '\\')
		out += '\\';
	out = out + *it + "' ";

	switch (*it)
	{
	case '~': out += "(using namespace)"; break;
	case '!': out += "(entity declaration)"; break;
	case '@': out += "(import)"; break;
	case '#': out += "(option)"; break;
	case '&': out += "(self)"; break;
	case ':': out += "(line string)"; break;
	case '"': out += "(cstring)"; break;
	case '?': out += "(entity declaration)"; break;
	case '.': out += "(scope)"; break;
	case '(': case ')':out += "(parenthesis / round bracket)"; break;
	case '{': case '}': out += "(brace / curly bracket)"; break;
	case '[': case ']': out += "(square bracket)"; break;
	case '<': case '>': out += "(angle bracket / chevron)"; break;
	default:
		break;
	}
	return out;
}

Dictionary Parser::parseDictionary()
{
	return parseContainer<Dictionary, ConType::DICTIONARY>(Dictionary(), [&](Dictionary& dict)
	{
		if (nextTag == Tag::C_STRING)
			addJsonKeyvalue(dict);
		else
			parseOtherValue(
				CaseKeyValue{ dict.addSafe(move(key), move(value)); },
				ErrorKeyOnly(ERROR_INPUT_DICTIONARY),
				ErrorValueOnly(ERROR_INPUT_DICTIONARY),
				ErrorAbstractEntity(ERROR_INPUT_DICTIONARY));
	});
}

List Parser::parseList()
{
	return parseContainer<List, ConType::LIST>(List(), [&](List& list)
	{
		list.add(parseValueOnly());
	});
}

Tuple Parser::parseTuple()
{
	return parseContainer<Tuple, ConType::TUPLE>(Tuple(), [&](Tuple& tuple)
	{
		parseOtherValue(
			CaseKeyValue{ tuple.addSafe(move(key), move(value)); },
			ErrorKeyOnly(ERROR_INPUT_TUPLE),
			CaseValueOnly{ tuple.add(move(value)); },
			ErrorAbstractEntity(ERROR_INPUT_TUPLE));
	});
}

List Parser::parseListText()
{
	return parseContainer<List, ConType::LIST>(List(), [&](List& list)
	{
		list.add(parseLineString());
	});
}
Tuple Parser::parseTupleText()
{
	return parseContainer<Tuple, ConType::TUPLE>(Tuple(), [&](Tuple& tuple)
	{
		tuple.add(parseLineString());
	});
}

Namespace Parser::parseNamespace(const string& name, const Namespace& previousNamespace)
{
	return parseContainer<Namespace, ConType::DICTIONARY>(Namespace(name, previousNamespace), [&](Namespace& nspace)
	{
		switch (*it)
		{
		case CHAR_ABSTRACT_ENTITY:
			++it;
			nspace.addSafe(parseAbstractEntity(nspace));
			break;
		case CHAR_CONCRETE_ENTITY:
			++it;
			nspace.addSafe(parseConcreteEntity());
			break;
		case CHAR_SELF:
			skipJunkToTag(++it, Tag::START_TEMPLATE);
			nspace.addSafe(Entity(string(name), parseTemplateHead()));
			break;
		default:
			throw runtime_error(ERROR_INPUT_NAMESPACE);
		}
	});
}

Enum Parser::parseEnum(const string& name)
{
	return parseContainer<Enum, ConType::LIST>(Enum(name), [&](Enum& tEnum)
	{
		if (nextTag != Tag::NAME_START)
			throw runtime_error(ERROR_UNEXPECTED);
		auto name = parseName(it);
		if (isKeyword(name))
			throw runtime_error("enum name can't be a keyword");
		tEnum.addSafe(move(name));
	});
}

Document Parser::parseDocument()
{
	try
	{
		Document doc;
		if (!containerEmpty() && !parseDocumentHead(doc.getHead(), Namespace::getEmptyInstance()))
		{
			do
				parseOtherValue(
					CaseKeyValue{ doc.addSafe(move(key), move(value)); },
					ErrorKeyOnly(ERROR_INPUT_DOCUMENT),
					CaseValueOnly{ doc.add(move(value)); },
					ErrorAbstractEntity(ERROR_INPUT_DOCUMENT));
			while (checkNextElement());
		}
		return doc;
	}
	catch (const exception& e)
	{
		throw runtime_error(string(getItPosition(it) + ' ' + e.what() + getItCurrentChar(it)).c_str());
	}
}

bool Parser::parseDocumentHead(vector<ParamDocument>& docHead, const Namespace& nspace)
{
	assert(it);
	do
	{
		switch (*it)
		{
		case CHAR_ABSTRACT_ENTITY:
		{
			++it;
			auto ent = parseAbstractEntity(nspace);
			docHead.push_back(ParamDocument::makeEntityAbstract(ent));
			ents.addLocalSafe(move(ent));
			break;
		}
		case CHAR_CONCRETE_ENTITY:
		{
			++it;
			auto ent = parseConcreteEntity();
			docHead.push_back(ParamDocument::makeEntityConcrete(ent));
			ents.addLocalSafe(move(ent));
			break;
		}
		case CHAR_IMPORT:
		{
			++it;
			auto import = parseImport();
			docHead.push_back(move(import));
			break;
		}
		case CHAR_SCOPED_DOCUMENT:
			++it;
			parseScopedDocument(docHead);
			break;
		default:
			return false;
		}
	} while (checkNextElement());
	return true;
}

void Parser::parseScopedDocument(vector<ParamDocument>& docHead)
{
	if (*skipJunkToValid(it) == OPEN_TEMPLATE)
	{
		ContainerSwitcher switcher1(*this, ConType::TEMPLATE_HEAD, false);
		if (containerEmpty())
			throw runtime_error("can't have empty scoped document head");

		auto head = parseTemplateHeadScoped();

		skipJunkToTag(it, Tag::START_DICTIONARY);
		DocumentHead body;

		ContainerSwitcher switcher2(*this, ConType::DICTIONARY, false);
		if (!containerEmpty())
		{
			ParamDocumentIncluder includer(ents, head.getParameters());
			if (!parseDocumentHead(body, Namespace::getEmptyInstance()))
				throw runtime_error(ERROR_UNEXPECTED);
		}
		docHead.push_back(ScopedDocument{ move(head), move(body) });
	}
	else
	{
		const auto& nspace = parseUsingNamespaceStatic();

		//first check the namespace entity is accessible; if so it has to be removed since
		//it'll no longer be necessary and an entity with the same name could be inside
		if (ParamDocumentIncluder::namespacePresentScope(ents, nspace))
			ents.removeLocal(ents[nspace.getName()]);

		for (const auto& ent : nspace)
			ents.addLocalSafe(ent);
	}
}

ImportedDocument Parser::parseImport()
{
#ifdef DISABLE_IMPORT
	throw runtime_error("this parser cannot import documents");
#else
	nextTag = getTag(it);
	auto importName = parseValueOnly();
	if (!importName.isString())
		throw runtime_error("import must reference a string");
	ImportedDocument import(move(importName));
	const auto& link = import.getLink();
	if (!importedDocuments.hasEntity(link))
	{
		try
		{
			importedDocuments.addLocalSafe(link, 0);
			ImportSwitcher switcher(*this, SmartIterator(Curl().readWebDocument(link)));
			DocumentHead docHead;
			if (!containerEmpty() && !parseDocumentHead(docHead, Namespace::getEmptyInstance()))
				throw runtime_error(ERROR_UNEXPECTED);
		}
		catch (const exception& e)
			{ throw runtime_error(string("while parsing import, ") + e.what()); }
	}
	return import;
#endif
}

const Namespace& Parser::parseUsingNamespaceStatic()
{
	skipJunkToTag(it, Tag::NAME_START);
	auto nameType = parseNameType();
	if (nameType.type != NameType::ENTITY_ABSTRACT || !nameType.entity.getContent().isNamespace())
		throw runtime_error("expected namespace");
	return nameType.entity.getContent().getNamespaceSafe();
}<|endoftext|>


<commit_before><commit_msg>Fixing a possible error source<commit_after><|endoftext|>


<commit_before>#include "pch.h"
#include "WASAPIDevice.h"

using namespace LibAudio;

WASAPIDevice::WASAPIDevice() : m_initialized(false)
{
}

void WASAPIDevice::StopAsync()
{
	if (Capture != nullptr)
	{
		Capture->StopCaptureAsync();
	}
}

void WASAPIDevice::InitCaptureDevice(size_t id, DataCollector^ collector)
{
	Number = id;
	if (Capture)
	{
		Capture = nullptr;
	}

	Capture = Make<WASAPICapture>();

	StateChangedEvent = Capture->GetDeviceStateEvent();
	DeviceStateChangeToken = StateChangedEvent->StateChangedEvent += ref new DeviceStateChangedHandler(this, &WASAPIDevice::OnDeviceStateChange);

	Capture->InitializeAudioDeviceAsync(ID, Number, collector);
	m_initialized = true;
}

void WASAPIDevice::InitRendererDevice(size_t id, DataCollector^ collector)
{
    HRESULT hr = S_OK;

    if (Renderer)
    {
		Renderer = nullptr;
	}

    Renderer = Make<WASAPIRenderer>();

    StateChangedEvent = Renderer->GetDeviceStateEvent();
	DeviceStateChangeToken = StateChangedEvent->StateChangedEvent += ref new DeviceStateChangedHandler(this, &WASAPIDevice::OnDeviceStateChange);

	DEVICEPROPS props;
	props.IsTonePlayback = true;
	props.Frequency = static_cast<DWORD>(440);
	/*
	switch (m_ContentType)
	{
	case ContentType::ContentTypeTone:
		props.IsTonePlayback = true;
		props.Frequency = static_cast<DWORD>(sliderFrequency->Value);
		break;

	case ContentType::ContentTypeFile:
		props.IsTonePlayback = false;
		props.ContentStream = m_ContentStream;
		break;
	}

	m_IsMinimumLatency = static_cast<Platform::Boolean>(toggleMinimumLatency->IsOn);

	props.IsLowLatency = m_IsMinimumLatency;
	props.IsHWOffload = false;
	props.IsBackground = false;
	props.IsRawChosen = static_cast<Platform::Boolean>(toggleRawAudio->IsOn);
	props.IsRawSupported = m_deviceSupportsRawMode;
	*/
	Renderer->SetProperties(props);

	Renderer->InitializeAudioDeviceAsync(ID, Number, collector);
	m_initialized = true;
}

void WASAPIDevice::OnDeviceStateChange(Object^ sender, DeviceStateChangedEventArgs^ e)
{
	// Get the current time for messages
	auto t = Windows::Globalization::DateTimeFormatting::DateTimeFormatter::LongTime;
	Windows::Globalization::Calendar^ calendar = ref new Windows::Globalization::Calendar();
	calendar->SetToNow();

	// Handle state specific messages
	switch (e->State)
	{
		case DeviceState::DeviceStateInitialized:
		{
			String^ str = String::Concat(ID, "-DeviceStateInitialized\n");
			OutputDebugString(str->Data());
			if (Capture != nullptr)
			{
				Capture->StartCaptureAsync();
			}
			if (Renderer != nullptr)
			{
				Renderer->StartPlaybackAsync();
			}
			break;
		}
		case DeviceState::DeviceStateCapturing:
		{
			String^ str = String::Concat(ID, "-DeviceStateCapturing\n");
			OutputDebugString(str->Data());
			break;
		}
		case DeviceState::DeviceStateDiscontinuity:
		{
			String^ str = String::Concat(ID, "-DeviceStateDiscontinuity\n");
			OutputDebugString(str->Data());
			break;
		}
		case DeviceState::DeviceStateInError:
		{
			String^ str = String::Concat(ID, "-DeviceStateInError\n");
			OutputDebugString(str->Data());
			break;
		}
	}
}
<commit_msg>12052016 - 12:53<commit_after>#include "pch.h"
#include "WASAPIDevice.h"

using namespace LibAudio;

WASAPIDevice::WASAPIDevice() : m_initialized(false)
{
}

void WASAPIDevice::StopAsync()
{
	if (Capture != nullptr)
	{
		Capture->StopCaptureAsync();
	}
}

void WASAPIDevice::InitCaptureDevice(size_t id, DataCollector^ collector)
{
	Number = id;
	if (Capture)
	{
		Capture = nullptr;
	}

	Capture = Make<WASAPICapture>();

	StateChangedEvent = Capture->GetDeviceStateEvent();
	DeviceStateChangeToken = StateChangedEvent->StateChangedEvent += ref new DeviceStateChangedHandler(this, &WASAPIDevice::OnDeviceStateChange);

	Capture->InitializeAudioDeviceAsync(ID, Number, collector);
	m_initialized = true;
}

void WASAPIDevice::InitRendererDevice(size_t id, DataCollector^ collector)
{
    HRESULT hr = S_OK;

    if (Renderer)
    {
		Renderer = nullptr;
	}

    Renderer = Make<WASAPIRenderer>();

    StateChangedEvent = Renderer->GetDeviceStateEvent();
	DeviceStateChangeToken = StateChangedEvent->StateChangedEvent += ref new DeviceStateChangedHandler(this, &WASAPIDevice::OnDeviceStateChange);

	DEVICEPROPS props;
	props.IsTonePlayback = true;
	props.Frequency = static_cast<DWORD>(440);
	/*
	switch (m_ContentType)
	{
	case ContentType::ContentTypeTone:
		props.IsTonePlayback = true;
		props.Frequency = static_cast<DWORD>(sliderFrequency->Value);
		break;

	case ContentType::ContentTypeFile:
		props.IsTonePlayback = false;
		props.ContentStream = m_ContentStream;
		break;
	}

	m_IsMinimumLatency = static_cast<Platform::Boolean>(toggleMinimumLatency->IsOn);

	props.IsLowLatency = m_IsMinimumLatency;
	props.IsHWOffload = false;
	props.IsBackground = false;
	props.IsRawChosen = static_cast<Platform::Boolean>(toggleRawAudio->IsOn);
	props.IsRawSupported = m_deviceSupportsRawMode;
	*/
	Renderer->SetProperties(props);

	Renderer->InitializeAudioDeviceAsync(ID, Number, collector);
	m_initialized = true;
}

void WASAPIDevice::OnDeviceStateChange(Object^ sender, DeviceStateChangedEventArgs^ e)
{
	// Get the current time for messages
	auto t = Windows::Globalization::DateTimeFormatting::DateTimeFormatter::LongTime;
	Windows::Globalization::Calendar^ calendar = ref new Windows::Globalization::Calendar();
	calendar->SetToNow();

	// Handle state specific messages
	switch (e->State)
	{
		case DeviceState::DeviceStateActivated:
		{
			String^ str = String::Concat(ID, "-DeviceStateActivated\n");
			OutputDebugString(str->Data());
			if (Renderer != nullptr)
			{
				Renderer->StartPlaybackAsync();
			}
			break;
		}
		case DeviceState::DeviceStateInitialized:
		{
			String^ str = String::Concat(ID, "-DeviceStateInitialized\n");
			OutputDebugString(str->Data());
			if (Capture != nullptr)
			{
				Capture->StartCaptureAsync();
			}
			break;
		}
		case DeviceState::DeviceStateCapturing:
		{
			String^ str = String::Concat(ID, "-DeviceStateCapturing\n");
			OutputDebugString(str->Data());
			break;
		}
		case DeviceState::DeviceStateDiscontinuity:
		{
			String^ str = String::Concat(ID, "-DeviceStateDiscontinuity\n");
			OutputDebugString(str->Data());
			break;
		}
		case DeviceState::DeviceStateInError:
		{
			String^ str = String::Concat(ID, "-DeviceStateInError\n");
			OutputDebugString(str->Data());
			break;
		}
	}
}
<|endoftext|>


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

#include "chrome/browser/policy/network_configuration_updater.h"

#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/cros/mock_network_library.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/policy_service_impl.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Mock;
using testing::Return;
using testing::_;

namespace policy {

static const char kFakeONC[] = "{ \"GUID\": \"1234\" }";

class NetworkConfigurationUpdaterTest
    : public testing::TestWithParam<const char*> {
 protected:
  virtual void SetUp() OVERRIDE {
    EXPECT_CALL(network_library_, LoadOncNetworks(_, "", _, _, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(provider_, IsInitializationComplete())
        .WillRepeatedly(Return(true));
    PolicyServiceImpl::Providers providers;
    providers.push_back(&provider_);
    policy_service_.reset(new PolicyServiceImpl(providers));
  }

  // Maps configuration policy name to corresponding ONC source.
  static chromeos::NetworkUIData::ONCSource NameToONCSource(
      const std::string& name) {
    if (name == key::kDeviceOpenNetworkConfiguration)
      return chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY;
    if (name == key::kOpenNetworkConfiguration)
      return chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY;
    return chromeos::NetworkUIData::ONC_SOURCE_NONE;
  }

  chromeos::MockNetworkLibrary network_library_;
  MockConfigurationPolicyProvider provider_;
  scoped_ptr<PolicyServiceImpl> policy_service_;
};

TEST_P(NetworkConfigurationUpdaterTest, InitialUpdate) {
  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);

  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .WillOnce(Return(true));

  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
  Mock::VerifyAndClearExpectations(&network_library_);
}

TEST_P(NetworkConfigurationUpdaterTest, AllowWebTrust) {
  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
  updater.set_allow_web_trust(true);

  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              true, _))
      .WillOnce(Return(true));

  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);
}

TEST_P(NetworkConfigurationUpdaterTest, PolicyChange) {
  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);

  // We should update if policy changes.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .WillOnce(Return(true));
  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);

  // No update if the set the same value again.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .Times(0);
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);

  // Another update is expected if the policy goes away.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(NetworkConfigurationUpdater::kEmptyConfiguration,
                              "", NameToONCSource(GetParam()), false, _))
      .WillOnce(Return(true));
  policy.Erase(GetParam());
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);
}

INSTANTIATE_TEST_CASE_P(
    NetworkConfigurationUpdaterTestInstance,
    NetworkConfigurationUpdaterTest,
    testing::Values(key::kDeviceOpenNetworkConfiguration,
                    key::kOpenNetworkConfiguration));

}  // namespace policy
<commit_msg>Update unit_test that broke after http://crrev.com/162481<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/policy/network_configuration_updater.h"

#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/cros/mock_network_library.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/policy_service_impl.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Mock;
using testing::Return;
using testing::_;

namespace policy {

static const char kFakeONC[] = "{ \"GUID\": \"1234\" }";

class NetworkConfigurationUpdaterTest
    : public testing::TestWithParam<const char*> {
 protected:
  virtual void SetUp() OVERRIDE {
    EXPECT_CALL(network_library_, LoadOncNetworks(_, "", _, _, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(provider_, IsInitializationComplete())
        .WillRepeatedly(Return(true));
    provider_.Init();
    PolicyServiceImpl::Providers providers;
    providers.push_back(&provider_);
    policy_service_.reset(new PolicyServiceImpl(providers));
  }

  virtual void TearDown() OVERRIDE {
    provider_.Shutdown();
  }

  // Maps configuration policy name to corresponding ONC source.
  static chromeos::NetworkUIData::ONCSource NameToONCSource(
      const std::string& name) {
    if (name == key::kDeviceOpenNetworkConfiguration)
      return chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY;
    if (name == key::kOpenNetworkConfiguration)
      return chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY;
    return chromeos::NetworkUIData::ONC_SOURCE_NONE;
  }

  chromeos::MockNetworkLibrary network_library_;
  MockConfigurationPolicyProvider provider_;
  scoped_ptr<PolicyServiceImpl> policy_service_;
};

TEST_P(NetworkConfigurationUpdaterTest, InitialUpdate) {
  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);

  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .WillOnce(Return(true));

  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
  Mock::VerifyAndClearExpectations(&network_library_);
}

TEST_P(NetworkConfigurationUpdaterTest, AllowWebTrust) {
  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);
  updater.set_allow_web_trust(true);

  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              true, _))
      .WillOnce(Return(true));

  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);
}

TEST_P(NetworkConfigurationUpdaterTest, PolicyChange) {
  NetworkConfigurationUpdater updater(policy_service_.get(), &network_library_);

  // We should update if policy changes.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .WillOnce(Return(true));
  PolicyMap policy;
  policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
             Value::CreateStringValue(kFakeONC));
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);

  // No update if the set the same value again.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(kFakeONC, "", NameToONCSource(GetParam()),
                              false, _))
      .Times(0);
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);

  // Another update is expected if the policy goes away.
  EXPECT_CALL(network_library_,
              LoadOncNetworks(NetworkConfigurationUpdater::kEmptyConfiguration,
                              "", NameToONCSource(GetParam()), false, _))
      .WillOnce(Return(true));
  policy.Erase(GetParam());
  provider_.UpdateChromePolicy(policy);
  Mock::VerifyAndClearExpectations(&network_library_);
}

INSTANTIATE_TEST_CASE_P(
    NetworkConfigurationUpdaterTestInstance,
    NetworkConfigurationUpdaterTest,
    testing::Values(key::kDeviceOpenNetworkConfiguration,
                    key::kOpenNetworkConfiguration));

}  // namespace policy
<|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/browser/tab_contents/render_view_host_delegate_helper.h"

#include "base/command_line.h"
#include "base/string_util.h"
#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"

BackgroundContents*
RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    GURL opener_url,
    const string16& frame_name) {
  ExtensionsService* extensions_service = profile->GetExtensionsService();

  if (!opener_url.is_valid() ||
      frame_name.empty() ||
      !extensions_service ||
      !extensions_service->is_ready())
    return NULL;

  Extension* extension = extensions_service->GetExtensionByURL(opener_url);
  if (!extension)
    extension = extensions_service->GetExtensionByWebExtent(opener_url);
  if (!extension ||
      !extension->HasApiPermission(Extension::kBackgroundPermission))
    return NULL;

  // Only allow a single background contents per app.
  if (!profile->GetBackgroundContentsService() ||
      profile->GetBackgroundContentsService()->GetAppBackgroundContents(
          ASCIIToUTF16(extension->id())))
    return NULL;

  // Ensure that we're trying to open this from the extension's process.
  ExtensionProcessManager* process_manager =
      profile->GetExtensionProcessManager();
  if (!site->GetProcess() || !process_manager ||
      site->GetProcess() != process_manager->GetExtensionProcess(opener_url))
    return NULL;

  // Passed all the checks, so this should be created as a BackgroundContents.
  BackgroundContents* contents = new BackgroundContents(site, route_id);
  string16 appid = ASCIIToUTF16(extension->id());
  BackgroundContentsOpenedDetails details = { contents, frame_name, appid };
  NotificationService::current()->Notify(
      NotificationType::BACKGROUND_CONTENTS_OPENED,
      Source<Profile>(profile),
      Details<BackgroundContentsOpenedDetails>(&details));

  return contents;
}

TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    DOMUITypeID domui_type,
    RenderViewHostDelegate* opener,
    WindowContainerType window_container_type,
    const string16& frame_name) {
  if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
    BackgroundContents* contents = MaybeCreateBackgroundContents(
        route_id,
        profile,
        site,
        opener->GetURL(),
        frame_name);
    if (contents) {
      pending_contents_[route_id] = contents->render_view_host();
      return NULL;
    }
  }

  // Create the new web contents. This will automatically create the new
  // TabContentsView. In the future, we may want to create the view separately.
  TabContents* new_contents =
      new TabContents(profile,
                      site,
                      route_id,
                      opener->GetAsTabContents());
  new_contents->set_opener_dom_ui_type(domui_type);
  TabContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents->render_view_host();
  return new_contents;
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::CreateNewWidget(
    int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  // Popups should not get activated.
  widget_view->set_popup_type(popup_type);
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderViewHost* new_rvh = iter->second;
  pending_contents_.erase(route_id);

  // The renderer crashed or it is a TabContents and has no view.
  if (!new_rvh->process()->HasConnection() ||
      (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view()))
    return NULL;

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_rvh->Init();
  return new_rvh->delegate()->GetAsTabContents();
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget(
    int route_id) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->HasConnection()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return NULL;
  }

  return widget_host_view;
}

void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed(
    RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

// static
WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
    Profile* profile, bool is_dom_ui) {
  PrefService* prefs = profile->GetPrefs();
  WebPreferences web_prefs;

  web_prefs.fixed_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitFixedFontFamily));
  web_prefs.serif_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitSerifFontFamily));
  web_prefs.sans_serif_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitSansSerifFontFamily));
  if (prefs->GetBoolean(prefs::kWebKitStandardFontIsSerif))
    web_prefs.standard_font_family = web_prefs.serif_font_family;
  else
    web_prefs.standard_font_family = web_prefs.sans_serif_font_family;
  web_prefs.cursive_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitCursiveFontFamily));
  web_prefs.fantasy_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitFantasyFontFamily));

  web_prefs.default_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFontSize);
  web_prefs.default_fixed_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
  web_prefs.minimum_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumFontSize);
  web_prefs.minimum_logical_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);

  web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);

  web_prefs.javascript_can_open_windows_automatically =
      prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
  web_prefs.dom_paste_enabled =
      prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
  web_prefs.shrinks_standalone_images_to_fit =
      prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
  const DictionaryValue* inspector_settings =
      prefs->GetDictionary(prefs::kWebKitInspectorSettings);
  if (inspector_settings) {
    for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys());
         iter != inspector_settings->end_keys(); ++iter) {
      std::string value;
      if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value))
          web_prefs.inspector_settings.push_back(
              std::make_pair(WideToUTF8(*iter), value));
    }
  }
  web_prefs.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);

  {  // Command line switches are used for preferences with no user interface.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    web_prefs.developer_extras_enabled =
        !command_line.HasSwitch(switches::kDisableDevTools);
    web_prefs.javascript_enabled =
        !command_line.HasSwitch(switches::kDisableJavaScript) &&
        prefs->GetBoolean(prefs::kWebKitJavascriptEnabled);
    web_prefs.web_security_enabled =
        !command_line.HasSwitch(switches::kDisableWebSecurity) &&
        prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled);
    web_prefs.plugins_enabled =
        !command_line.HasSwitch(switches::kDisablePlugins) &&
        prefs->GetBoolean(prefs::kWebKitPluginsEnabled);
    web_prefs.java_enabled =
        !command_line.HasSwitch(switches::kDisableJava) &&
        prefs->GetBoolean(prefs::kWebKitJavaEnabled);
    web_prefs.loads_images_automatically =
        prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
    web_prefs.uses_page_cache =
        command_line.HasSwitch(switches::kEnableFastback);
    web_prefs.remote_fonts_enabled =
        !command_line.HasSwitch(switches::kDisableRemoteFonts);
    web_prefs.xss_auditor_enabled =
        command_line.HasSwitch(switches::kEnableXSSAuditor);
    web_prefs.application_cache_enabled =
        !command_line.HasSwitch(switches::kDisableApplicationCache);

    web_prefs.local_storage_enabled =
        !command_line.HasSwitch(switches::kDisableLocalStorage);
    web_prefs.databases_enabled =
        !command_line.HasSwitch(switches::kDisableDatabases);
    web_prefs.experimental_webgl_enabled =
        command_line.HasSwitch(switches::kEnableExperimentalWebGL);
    web_prefs.site_specific_quirks_enabled =
        !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
    web_prefs.allow_file_access_from_file_urls =
        command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
    web_prefs.show_composited_layer_borders =
        command_line.HasSwitch(switches::kShowCompositedLayerBorders);
    web_prefs.accelerated_compositing_enabled =
        command_line.HasSwitch(switches::kEnableAcceleratedCompositing);
    web_prefs.accelerated_2d_canvas_enabled =
        command_line.HasSwitch(switches::kEnableAccelerated2dCanvas);
    web_prefs.memory_info_enabled =
        command_line.HasSwitch(switches::kEnableMemoryInfo);
    // The user stylesheet watcher may not exist in a testing profile.
    if (profile->GetUserStyleSheetWatcher()) {
      web_prefs.user_style_sheet_enabled = true;
      web_prefs.user_style_sheet_location =
          profile->GetUserStyleSheetWatcher()->user_style_sheet();
    } else {
      web_prefs.user_style_sheet_enabled = false;
    }
  }

  web_prefs.uses_universal_detector =
      prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
  web_prefs.text_areas_are_resizable =
      prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);

  // Make sure we will set the default_encoding with canonical encoding name.
  web_prefs.default_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName(
          web_prefs.default_encoding);
  if (web_prefs.default_encoding.empty()) {
    prefs->ClearPref(prefs::kDefaultCharset);
    web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);
  }
  DCHECK(!web_prefs.default_encoding.empty());

  if (is_dom_ui) {
    web_prefs.loads_images_automatically = true;
    web_prefs.javascript_enabled = true;
  }

  return web_prefs;
}
<commit_msg>Remove unneeded browser.h include from RVHDelegateHelper.<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/browser/tab_contents/render_view_host_delegate_helper.h"

#include "base/command_line.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"

BackgroundContents*
RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    GURL opener_url,
    const string16& frame_name) {
  ExtensionsService* extensions_service = profile->GetExtensionsService();

  if (!opener_url.is_valid() ||
      frame_name.empty() ||
      !extensions_service ||
      !extensions_service->is_ready())
    return NULL;

  Extension* extension = extensions_service->GetExtensionByURL(opener_url);
  if (!extension)
    extension = extensions_service->GetExtensionByWebExtent(opener_url);
  if (!extension ||
      !extension->HasApiPermission(Extension::kBackgroundPermission))
    return NULL;

  // Only allow a single background contents per app.
  if (!profile->GetBackgroundContentsService() ||
      profile->GetBackgroundContentsService()->GetAppBackgroundContents(
          ASCIIToUTF16(extension->id())))
    return NULL;

  // Ensure that we're trying to open this from the extension's process.
  ExtensionProcessManager* process_manager =
      profile->GetExtensionProcessManager();
  if (!site->GetProcess() || !process_manager ||
      site->GetProcess() != process_manager->GetExtensionProcess(opener_url))
    return NULL;

  // Passed all the checks, so this should be created as a BackgroundContents.
  BackgroundContents* contents = new BackgroundContents(site, route_id);
  string16 appid = ASCIIToUTF16(extension->id());
  BackgroundContentsOpenedDetails details = { contents, frame_name, appid };
  NotificationService::current()->Notify(
      NotificationType::BACKGROUND_CONTENTS_OPENED,
      Source<Profile>(profile),
      Details<BackgroundContentsOpenedDetails>(&details));

  return contents;
}

TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    DOMUITypeID domui_type,
    RenderViewHostDelegate* opener,
    WindowContainerType window_container_type,
    const string16& frame_name) {
  if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
    BackgroundContents* contents = MaybeCreateBackgroundContents(
        route_id,
        profile,
        site,
        opener->GetURL(),
        frame_name);
    if (contents) {
      pending_contents_[route_id] = contents->render_view_host();
      return NULL;
    }
  }

  // Create the new web contents. This will automatically create the new
  // TabContentsView. In the future, we may want to create the view separately.
  TabContents* new_contents =
      new TabContents(profile,
                      site,
                      route_id,
                      opener->GetAsTabContents());
  new_contents->set_opener_dom_ui_type(domui_type);
  TabContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents->render_view_host();
  return new_contents;
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::CreateNewWidget(
    int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  // Popups should not get activated.
  widget_view->set_popup_type(popup_type);
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderViewHost* new_rvh = iter->second;
  pending_contents_.erase(route_id);

  // The renderer crashed or it is a TabContents and has no view.
  if (!new_rvh->process()->HasConnection() ||
      (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view()))
    return NULL;

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_rvh->Init();
  return new_rvh->delegate()->GetAsTabContents();
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget(
    int route_id) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->HasConnection()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return NULL;
  }

  return widget_host_view;
}

void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed(
    RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

// static
WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
    Profile* profile, bool is_dom_ui) {
  PrefService* prefs = profile->GetPrefs();
  WebPreferences web_prefs;

  web_prefs.fixed_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitFixedFontFamily));
  web_prefs.serif_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitSerifFontFamily));
  web_prefs.sans_serif_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitSansSerifFontFamily));
  if (prefs->GetBoolean(prefs::kWebKitStandardFontIsSerif))
    web_prefs.standard_font_family = web_prefs.serif_font_family;
  else
    web_prefs.standard_font_family = web_prefs.sans_serif_font_family;
  web_prefs.cursive_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitCursiveFontFamily));
  web_prefs.fantasy_font_family =
      UTF8ToWide(prefs->GetString(prefs::kWebKitFantasyFontFamily));

  web_prefs.default_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFontSize);
  web_prefs.default_fixed_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
  web_prefs.minimum_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumFontSize);
  web_prefs.minimum_logical_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);

  web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);

  web_prefs.javascript_can_open_windows_automatically =
      prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
  web_prefs.dom_paste_enabled =
      prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
  web_prefs.shrinks_standalone_images_to_fit =
      prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
  const DictionaryValue* inspector_settings =
      prefs->GetDictionary(prefs::kWebKitInspectorSettings);
  if (inspector_settings) {
    for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys());
         iter != inspector_settings->end_keys(); ++iter) {
      std::string value;
      if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value))
          web_prefs.inspector_settings.push_back(
              std::make_pair(WideToUTF8(*iter), value));
    }
  }
  web_prefs.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);

  {  // Command line switches are used for preferences with no user interface.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    web_prefs.developer_extras_enabled =
        !command_line.HasSwitch(switches::kDisableDevTools);
    web_prefs.javascript_enabled =
        !command_line.HasSwitch(switches::kDisableJavaScript) &&
        prefs->GetBoolean(prefs::kWebKitJavascriptEnabled);
    web_prefs.web_security_enabled =
        !command_line.HasSwitch(switches::kDisableWebSecurity) &&
        prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled);
    web_prefs.plugins_enabled =
        !command_line.HasSwitch(switches::kDisablePlugins) &&
        prefs->GetBoolean(prefs::kWebKitPluginsEnabled);
    web_prefs.java_enabled =
        !command_line.HasSwitch(switches::kDisableJava) &&
        prefs->GetBoolean(prefs::kWebKitJavaEnabled);
    web_prefs.loads_images_automatically =
        prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
    web_prefs.uses_page_cache =
        command_line.HasSwitch(switches::kEnableFastback);
    web_prefs.remote_fonts_enabled =
        !command_line.HasSwitch(switches::kDisableRemoteFonts);
    web_prefs.xss_auditor_enabled =
        command_line.HasSwitch(switches::kEnableXSSAuditor);
    web_prefs.application_cache_enabled =
        !command_line.HasSwitch(switches::kDisableApplicationCache);

    web_prefs.local_storage_enabled =
        !command_line.HasSwitch(switches::kDisableLocalStorage);
    web_prefs.databases_enabled =
        !command_line.HasSwitch(switches::kDisableDatabases);
    web_prefs.experimental_webgl_enabled =
        command_line.HasSwitch(switches::kEnableExperimentalWebGL);
    web_prefs.site_specific_quirks_enabled =
        !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
    web_prefs.allow_file_access_from_file_urls =
        command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
    web_prefs.show_composited_layer_borders =
        command_line.HasSwitch(switches::kShowCompositedLayerBorders);
    web_prefs.accelerated_compositing_enabled =
        command_line.HasSwitch(switches::kEnableAcceleratedCompositing);
    web_prefs.accelerated_2d_canvas_enabled =
        command_line.HasSwitch(switches::kEnableAccelerated2dCanvas);
    web_prefs.memory_info_enabled =
        command_line.HasSwitch(switches::kEnableMemoryInfo);
    // The user stylesheet watcher may not exist in a testing profile.
    if (profile->GetUserStyleSheetWatcher()) {
      web_prefs.user_style_sheet_enabled = true;
      web_prefs.user_style_sheet_location =
          profile->GetUserStyleSheetWatcher()->user_style_sheet();
    } else {
      web_prefs.user_style_sheet_enabled = false;
    }
  }

  web_prefs.uses_universal_detector =
      prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
  web_prefs.text_areas_are_resizable =
      prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);

  // Make sure we will set the default_encoding with canonical encoding name.
  web_prefs.default_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName(
          web_prefs.default_encoding);
  if (web_prefs.default_encoding.empty()) {
    prefs->ClearPref(prefs::kDefaultCharset);
    web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);
  }
  DCHECK(!web_prefs.default_encoding.empty());

  if (is_dom_ui) {
    web_prefs.loads_images_automatically = true;
    web_prefs.javascript_enabled = true;
  }

  return web_prefs;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <limits>
#include <fstream>
#include <sstream>
#include <vector>
#include <stb/stb_image.h>
#include <stb/stb_image_resize.h>
#include <stb/stb_image_write.h>
#include "ImageUtils.h"
#include "PaletteWindow.h"
#include "SummaryView.h"

SummaryView::SummaryView(int size, int tileCount, int offsetX, int offsetY, int visibleSideCount, int reductionFactor)
    : isAlive(false), size(size), tileId(tileCount), selectedTile(2955),
      topographicSummarizer(size, tileCount, offsetX, offsetY, visibleSideCount, reductionFactor, "../ContourTiler/rasters/summary/", "summary.png"),
      overlaySummarizer(size, tileCount, offsetX, offsetY, visibleSideCount, reductionFactor, "../ContourTiler/rasters/summary/", "overlay.png"),
      windowSelf(nullptr), offsetX(offsetX), offsetY(offsetY), visibleSideCount(visibleSideCount)
{
}

void SummaryView::RemapToTile(double* x, double* y)
{
    int tileX, tileY;
    tileId.GetPositionFromId(selectedTile, &tileX, &tileY);

    (*x) *= ((double)1000 * tileId.GetTileCount());
    (*y) *= ((double)1000 * tileId.GetTileCount());

    (*x) -= (tileX * 1000);
    (*y) -= (tileY * 1000);
}

void SummaryView::MoveSelectedTile(Direction direction)
{
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);

    switch (direction)
    {
    case UP: ++y; break;
    case DOWN: --y; break;
    case LEFT: --x; break;
    case RIGHT: ++x; break;
    }

    if (topographicSummarizer.IsTileValid(x, y))
    {
        selectedTile = tileId.GetTileId(x, y);
        UpdateSelectedTileRectangle();

        // TODO this doesn't apply on startup, and should be fixed to not pass around the window pointer.
        if (windowSelf != nullptr)
        {
            std::stringstream titleString;
            titleString << "Summary (" << x << ", " << y << ")" << std::endl;
            windowSelf->setTitle(titleString.str());
        }
    }
}

void SummaryView::LoadSelectedTile(unsigned char** data, int offsetX, int offsetY)
{
    if (*data != nullptr)
    {
        // We could also do topographic, but we (for now) don't support elevation changes with this program.

        ImageUtils::FreeImage(*data);
        *data = nullptr;
    }

    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);

    x += offsetX;
    y += offsetY;

    // Ensure we read a valid image.
    x = std::max(0, x);
    y = std::max(0, y);
    x = std::min(x, tileId.GetTileCount() - 1);
    y = std::min(y, tileId.GetTileCount() - 1);

    std::stringstream imageTile;
    imageTile << "../ContourTiler/rasters/" << y << "/" << x << ".png";

    int width, height;
    if (!ImageUtils::LoadImage(imageTile.str().c_str(), &width, &height, data))
    {
        std::cout << "Failed to load " << imageTile.str() << std::endl;
    }
}

void SummaryView::LoadSelectedTile(bool loadEdges, unsigned char** centerData, unsigned char** leftData, unsigned char** rightData, unsigned char** topData, unsigned char** bottomData)
{
    LoadSelectedTile(centerData, 0, 0);

    // Don't reload the edges if we aren't saving when moving to speed up drawing
    if (loadEdges)
    {
        LoadSelectedTile(leftData, -1, 0);
        LoadSelectedTile(rightData, 1, 0);
        LoadSelectedTile(topData, 0, 1);
        LoadSelectedTile(bottomData, 0, -1);
    }
}

// We know that only the topographic data is what really matters. We do need to indicate a reload to both topographic and overlay layers though.
void SummaryView::UpdateSelectedTile(unsigned char* newData)
{
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);
    topographicSummarizer.UpdateSummaryForTile(newData, x, y, true);
    overlaySummarizer.UpdateSummaryForTile(newData, x, y, false);
}

void SummaryView::UpdateSelectedTileRectangle()
{
    int motionScale = size / visibleSideCount;
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);
    selectedTileRectangle.setPosition(sf::Vector2f((float)((x - offsetX) * motionScale), (float)(size - (y - offsetY + 1) * motionScale)));
}

void SummaryView::HandleEvents(sf::RenderWindow& window)
{
    // Handle all events.
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        {
            // Ignore -- we only close if the main map editor closes.
        }
    }
}

void SummaryView::Render(sf::RenderWindow& window)
{
    window.draw(topographicSummarizer.GetSummarizedSprite());
    window.draw(overlaySummarizer.GetSummarizedSprite());
    window.draw(selectedTileRectangle);
}

void SummaryView::ThreadStart()
{
    topographicSummarizer.Initialize(
        [](unsigned char r, unsigned char g, unsigned char b, unsigned char a) -> float
        {
            return ((float)((unsigned short)r + (((unsigned short)g) << 8))) / (float)std::numeric_limits<unsigned short>::max();
        },
        [](float value, unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) -> void
        {
            unsigned short averageValue = (unsigned short)(value * (float)std::numeric_limits<unsigned short>::max());
            unsigned char actualValue = (unsigned char)(averageValue / 256);
            *r = actualValue;
            *g = actualValue;
            *b = actualValue;
            *a = 255;
        });

    overlaySummarizer.Initialize(
        [](unsigned char r, unsigned char g, unsigned char b, unsigned char a) -> float
        {
            return (float)b;
        },
        [](float value, unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) -> void
        {
            // This will probably look odd but it's the best I can do.
            unsigned char averageValue = (unsigned char)value;
            PaletteWindow::TerrainType type = PaletteWindow::GetNearestTerrainType(averageValue);
            sf::Color color = PaletteWindow::GetTerrainColor(type);
            *r = color.r;
            *g = color.g;
            *b = color.b;
            *a = 110;
        });

    selectedTileRectangle = sf::RectangleShape(sf::Vector2f((float)(size / visibleSideCount), (float)(size / visibleSideCount)));
    selectedTileRectangle.setFillColor(sf::Color(0, 0, 0, 0));
    selectedTileRectangle.setOutlineThickness(1.0f);
    selectedTileRectangle.setOutlineColor(sf::Color::Green);
    UpdateSelectedTileRectangle();

    // 24 depth bits, 8 stencil bits, 8x AA, major version 4.
    sf::ContextSettings contextSettings = sf::ContextSettings(24, 8, 8, 4, 0);

    sf::Uint32 style = sf::Style::Titlebar;
    sf::RenderWindow window(sf::VideoMode(size, size), "Summary", style, contextSettings);
    window.setFramerateLimit(60);

    // TODO
    windowSelf = &window;

    // Start the main loop
    isAlive = true;
    while (isAlive)
    {
        HandleEvents(window);
        Render(window);

        // Display what we rendered.
        window.display();
    }
}

void SummaryView::Start()
{
    executionThread = new std::thread(&SummaryView::ThreadStart, this);
    while (!isAlive)
    {
        sf::sleep(sf::milliseconds(50));
    }
}

void SummaryView::Stop()
{
    isAlive = false;
    executionThread->join();
    delete executionThread;
}<commit_msg>Fudge factor necessary for the summary to be correct. Going to take a whil e to draw in all the tiles.<commit_after>#include <iostream>
#include <limits>
#include <fstream>
#include <sstream>
#include <vector>
#include <stb/stb_image.h>
#include <stb/stb_image_resize.h>
#include <stb/stb_image_write.h>
#include "ImageUtils.h"
#include "PaletteWindow.h"
#include "SummaryView.h"

SummaryView::SummaryView(int size, int tileCount, int offsetX, int offsetY, int visibleSideCount, int reductionFactor)
    : isAlive(false), size(size), tileId(tileCount), selectedTile(2955),
      topographicSummarizer(size, tileCount, offsetX, offsetY, visibleSideCount, reductionFactor, "../ContourTiler/rasters/summary/", "summary.png"),
      overlaySummarizer(size, tileCount, offsetX, offsetY, visibleSideCount, reductionFactor, "../ContourTiler/rasters/summary/", "overlay.png"),
      windowSelf(nullptr), offsetX(offsetX), offsetY(offsetY), visibleSideCount(visibleSideCount)
{
}

void SummaryView::RemapToTile(double* x, double* y)
{
    int tileX, tileY;
    tileId.GetPositionFromId(selectedTile, &tileX, &tileY);

    (*x) *= ((double)1000 * tileId.GetTileCount());
    (*y) *= ((double)1000 * tileId.GetTileCount());

    (*x) -= (tileX * 1000);
    (*y) -= (tileY * 1000);
}

void SummaryView::MoveSelectedTile(Direction direction)
{
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);

    switch (direction)
    {
    case UP: ++y; break;
    case DOWN: --y; break;
    case LEFT: --x; break;
    case RIGHT: ++x; break;
    }

    if (topographicSummarizer.IsTileValid(x, y))
    {
        selectedTile = tileId.GetTileId(x, y);
        UpdateSelectedTileRectangle();

        // TODO this doesn't apply on startup, and should be fixed to not pass around the window pointer.
        if (windowSelf != nullptr)
        {
            std::stringstream titleString;
            titleString << "Summary (" << x << ", " << y << ")" << std::endl;
            windowSelf->setTitle(titleString.str());
        }
    }
}

void SummaryView::LoadSelectedTile(unsigned char** data, int offsetX, int offsetY)
{
    if (*data != nullptr)
    {
        // We could also do topographic, but we (for now) don't support elevation changes with this program.

        ImageUtils::FreeImage(*data);
        *data = nullptr;
    }

    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);

    x += offsetX;
    y += offsetY;

    // Ensure we read a valid image.
    x = std::max(0, x);
    y = std::max(0, y);
    x = std::min(x, tileId.GetTileCount() - 1);
    y = std::min(y, tileId.GetTileCount() - 1);

    std::stringstream imageTile;
    imageTile << "../ContourTiler/rasters/" << y << "/" << x << ".png";

    int width, height;
    if (!ImageUtils::LoadImage(imageTile.str().c_str(), &width, &height, data))
    {
        std::cout << "Failed to load " << imageTile.str() << std::endl;
    }
}

void SummaryView::LoadSelectedTile(bool loadEdges, unsigned char** centerData, unsigned char** leftData, unsigned char** rightData, unsigned char** topData, unsigned char** bottomData)
{
    LoadSelectedTile(centerData, 0, 0);

    // Don't reload the edges if we aren't saving when moving to speed up drawing
    if (loadEdges)
    {
        LoadSelectedTile(leftData, -1, 0);
        LoadSelectedTile(rightData, 1, 0);
        LoadSelectedTile(topData, 0, 1);
        LoadSelectedTile(bottomData, 0, -1);
    }
}

// We know that only the topographic data is what really matters. We do need to indicate a reload to both topographic and overlay layers though.
void SummaryView::UpdateSelectedTile(unsigned char* newData)
{
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);
    topographicSummarizer.UpdateSummaryForTile(newData, x, y, true);
    overlaySummarizer.UpdateSummaryForTile(newData, x, y, false);
}

void SummaryView::UpdateSelectedTileRectangle()
{
    int motionScale = size / visibleSideCount;
    int x, y;
    tileId.GetPositionFromId(selectedTile, &x, &y);
    selectedTileRectangle.setPosition(sf::Vector2f((float)((x - offsetX) * motionScale), (float)(size - (y - offsetY + 1) * motionScale)));
}

void SummaryView::HandleEvents(sf::RenderWindow& window)
{
    // Handle all events.
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        {
            // Ignore -- we only close if the main map editor closes.
        }
    }
}

void SummaryView::Render(sf::RenderWindow& window)
{
    window.draw(topographicSummarizer.GetSummarizedSprite());
    window.draw(overlaySummarizer.GetSummarizedSprite());
    window.draw(selectedTileRectangle);
}

void SummaryView::ThreadStart()
{
    topographicSummarizer.Initialize(
        [](unsigned char r, unsigned char g, unsigned char b, unsigned char a) -> float
        {
            return ((float)((unsigned short)r + (((unsigned short)g) << 8))) / (float)std::numeric_limits<unsigned short>::max();
        },
        [](float value, unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) -> void
        {
            unsigned short averageValue = (unsigned short)(value * (float)std::numeric_limits<unsigned short>::max());
            unsigned char actualValue = (unsigned char)(averageValue / 256);
            *r = actualValue;
            *g = actualValue;
            *b = actualValue;
            *a = 255;
        });

    overlaySummarizer.Initialize(
        [](unsigned char r, unsigned char g, unsigned char b, unsigned char a) -> float
        {
            return (float)b;
        },
        [](float value, unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) -> void
        {
            // This will probably look odd but it's the best I can do.
            unsigned char averageValue = (unsigned char)value;
            PaletteWindow::TerrainType type = PaletteWindow::GetNearestTerrainType(averageValue > 250 ? averageValue : averageValue + 10);
            sf::Color color = PaletteWindow::GetTerrainColor(type);
            *r = color.r;
            *g = color.g;
            *b = color.b;
            *a = 110;
        });

    selectedTileRectangle = sf::RectangleShape(sf::Vector2f((float)(size / visibleSideCount), (float)(size / visibleSideCount)));
    selectedTileRectangle.setFillColor(sf::Color(0, 0, 0, 0));
    selectedTileRectangle.setOutlineThickness(1.0f);
    selectedTileRectangle.setOutlineColor(sf::Color::Green);
    UpdateSelectedTileRectangle();

    // 24 depth bits, 8 stencil bits, 8x AA, major version 4.
    sf::ContextSettings contextSettings = sf::ContextSettings(24, 8, 8, 4, 0);

    sf::Uint32 style = sf::Style::Titlebar;
    sf::RenderWindow window(sf::VideoMode(size, size), "Summary", style, contextSettings);
    window.setFramerateLimit(60);

    // TODO
    windowSelf = &window;

    // Start the main loop
    isAlive = true;
    while (isAlive)
    {
        HandleEvents(window);
        Render(window);

        // Display what we rendered.
        window.display();
    }
}

void SummaryView::Start()
{
    executionThread = new std::thread(&SummaryView::ThreadStart, this);
    while (!isAlive)
    {
        sf::sleep(sf::milliseconds(50));
    }
}

void SummaryView::Stop()
{
    isAlive = false;
    executionThread->join();
    delete executionThread;
}<|endoftext|>