<commit_before>//
//
// Copyright (c) 2017 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
//
// Distributed under the MIT Software License
//
#pragma once

#include <algorithm>
#include <cassert>
#include <type_traits>

#include "common.ipp"

namespace bredis {

template <typename NextLayer>
template <typename WriteCallback>
void Connection<NextLayer>::async_write(const command_wrapper_t &command,
                                        WriteCallback write_callback) {
    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::async_write;

    auto str = std::make_shared<std::string>(
        boost::apply_visitor(command_serializer_visitor(), command));
    auto str_ptr = str.get();
    BREDIS_LOG_DEBUG("async_write >> " << str_ptr->c_str());
    auto const output_buf = asio::buffer(str_ptr->c_str(), str_ptr->size());

    async_write(stream_, output_buf,
                [str, write_callback](const sys::error_code &error_code,
                                      std::size_t bytes_transferred) {
                    write_callback(error_code);
                });
}

template <typename NextLayer>
template <typename ReadCallback, typename DynamicBuffer>
void Connection<NextLayer>::async_read(DynamicBuffer &rx_buff,
                                       ReadCallback read_callback,
                                       std::size_t replies_count) {

    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::async_read_until;

    BREDIS_LOG_DEBUG("async_read");

    async_read_until(
        stream_, rx_buff, MatchResult(replies_count),
        [read_callback, &rx_buff, replies_count](
            const sys::error_code &error_code, std::size_t bytes_transferred) {
            if (error_code) {
                read_callback(error_code, {}, 0);
                return;
            }

            auto const_buff = rx_buff.data();
            const char *char_ptr =
                boost::asio::buffer_cast<const char *>(const_buff);
            auto size = rx_buff.size();
            BREDIS_LOG_DEBUG("incoming data("
                             << size << ") : " << char_ptr
                             << ", tx bytes: " << bytes_transferred);

            array_holder_t results;
            results.elements.reserve(replies_count);
            size_t cumulative_consumption = 0;
            boost::system::error_code ec;

            do {
                string_t data(char_ptr + cumulative_consumption,
                              size - cumulative_consumption);
                BREDIS_LOG_DEBUG("trying to get response # "
                                 << results.elements.size());
                BREDIS_LOG_DEBUG("trying to get response from " << data);
                auto parse_result = Protocol::parse(data);
                auto *parse_error = boost::get<protocol_error_t>(&parse_result);
                if (parse_error) {
                    /* might happen only in case of protocol error */
                    BREDIS_LOG_DEBUG("protocol error: " << parse_error->what);
                    auto parse_error_code =
                        Error::make_error_code(bredis_errors::protocol_error);
                    read_callback(parse_error_code, {}, 0);
                    return;
                }
                auto &positive_result =
                    boost::get<positive_parse_result_t>(parse_result);
                results.elements.emplace_back(positive_result.result);
                cumulative_consumption += positive_result.consumed;
            } while (results.elements.size() < replies_count);

            if (replies_count == 1) {
                read_callback(ec, std::move(results.elements[0]),
                              cumulative_consumption);
            } else {
                read_callback(ec, std::move(results), cumulative_consumption);
            }
        });
}

template <typename NextLayer>
void Connection<NextLayer>::write(const command_wrapper_t &command) {
    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::write;

    auto str = boost::apply_visitor(command_serializer_visitor(), command);
    BREDIS_LOG_DEBUG("async_write >> " << str);
    auto const output_buf = asio::buffer(str.c_str(), str.size());
    write(stream_, output_buf);
}

template <typename NextLayer>
void Connection<NextLayer>::write(const command_wrapper_t &command,
                                  boost::system::error_code &ec) {
    namespace asio = boost::asio;
    namespace sys = boost::system;

    auto str = boost::apply_visitor(command_serializer_visitor(), command);
    BREDIS_LOG_DEBUG("async_write >> " << str);
    auto const output_buf = asio::buffer(str.c_str(), str.size());
    asio::write(stream_, output_buf, ec);
}

template <typename NextLayer>
template <typename DynamicBuffer>
positive_parse_result_t
Connection<NextLayer>::read(DynamicBuffer &rx_buff,
                            boost::system::error_code &ec) {
    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::read_until;

    auto rx_bytes = read_until(stream_, rx_buff, MatchResult(1), ec);
    if (ec) {
        return positive_parse_result_t{{}, 0};
    }

    const auto char_ptr =
        boost::asio::buffer_cast<const char *>(rx_buff.data());
    auto size = rx_buff.size();
    string_t data(char_ptr, size);
    BREDIS_LOG_DEBUG("incoming data(" << size << ") : " << char_ptr);

    auto parse_result = Protocol::parse(data);
    auto *parse_error = boost::get<protocol_error_t>(&parse_result);
    if (parse_error) {
        BREDIS_LOG_DEBUG("protocol error: " << parse_error->what);
        ec = Error::make_error_code(bredis_errors::protocol_error);
        return positive_parse_result_t{{}, 0};
    }
    return boost::get<positive_parse_result_t>(parse_result);
}

template <typename NextLayer>
template <typename DynamicBuffer>
inline positive_parse_result_t
Connection<NextLayer>::read(DynamicBuffer &rx_buff) {
    namespace asio = boost::asio;
    namespace sys = boost::system;

    boost::system::error_code ec;
    auto result = read(rx_buff, ec);
    if (ec) {
        throw boost::system::system_error{ec};
    }
    return result;
}

} // namespace bredis
<commit_msg>simplify things<commit_after>//
//
// Copyright (c) 2017 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
//
// Distributed under the MIT Software License
//
#pragma once

#include <algorithm>
#include <cassert>
#include <type_traits>

#include "common.ipp"

namespace bredis {

template <typename NextLayer>
template <typename WriteCallback>
void Connection<NextLayer>::async_write(const command_wrapper_t &command,
                                        WriteCallback write_callback) {
    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::async_write;

    auto str = std::make_shared<std::string>(
        boost::apply_visitor(command_serializer_visitor(), command));
    auto str_ptr = str.get();
    BREDIS_LOG_DEBUG("async_write >> " << str_ptr->c_str());
    auto const output_buf = asio::buffer(str_ptr->c_str(), str_ptr->size());

    async_write(stream_, output_buf,
                [str, write_callback](const sys::error_code &error_code,
                                      std::size_t bytes_transferred) {
                    write_callback(error_code);
                });
}

template <typename NextLayer>
template <typename ReadCallback, typename DynamicBuffer>
void Connection<NextLayer>::async_read(DynamicBuffer &rx_buff,
                                       ReadCallback read_callback,
                                       std::size_t replies_count) {

    namespace asio = boost::asio;
    namespace sys = boost::system;
    using boost::asio::async_read_until;

    BREDIS_LOG_DEBUG("async_read");

    async_read_until(
        stream_, rx_buff, MatchResult(replies_count),
        [read_callback, &rx_buff, replies_count](
            const sys::error_code &error_code, std::size_t bytes_transferred) {
            if (error_code) {
                read_callback(error_code, {}, 0);
                return;
            }

            auto const_buff = rx_buff.data();
            const char *char_ptr =
                boost::asio::buffer_cast<const char *>(const_buff);
            auto size = rx_buff.size();
            BREDIS_LOG_DEBUG("incoming data("
                             << size << ") : " << char_ptr
                             << ", tx bytes: " << bytes_transferred);

            array_holder_t results;
            results.elements.reserve(replies_count);
            size_t cumulative_consumption = 0;
            boost::system::error_code ec;

            do {
                string_t data(char_ptr + cumulative_consumption,
                              size - cumulative_consumption);
                BREDIS_LOG_DEBUG("trying to get response # "
                                 << results.elements.size());
                BREDIS_LOG_DEBUG("trying to get response from " << data);
                auto parse_result = Protocol::parse(data);
                auto *parse_error = boost::get<protocol_error_t>(&parse_result);
                if (parse_error) {
                    /* might happen only in case of protocol error */
                    BREDIS_LOG_DEBUG("protocol error: " << parse_error->what);
                    auto parse_error_code =
                        Error::make_error_code(bredis_errors::protocol_error);
                    read_callback(parse_error_code, {}, 0);
                    return;
                }
                auto &positive_result =
                    boost::get<positive_parse_result_t>(parse_result);
                results.elements.emplace_back(positive_result.result);
                cumulative_consumption += positive_result.consumed;
            } while (results.elements.size() < replies_count);

            if (replies_count == 1) {
                read_callback(ec, std::move(results.elements[0]),
                              cumulative_consumption);
            } else {
                read_callback(ec, std::move(results), cumulative_consumption);
            }
        });
}

template <typename NextLayer>
void Connection<NextLayer>::write(const command_wrapper_t &command,
                                  boost::system::error_code &ec) {
    namespace asio = boost::asio;
    auto str = boost::apply_visitor(command_serializer_visitor(), command);
    BREDIS_LOG_DEBUG("async_write >> " << str);
    auto const output_buf = asio::buffer(str.c_str(), str.size());
    asio::write(stream_, output_buf, ec);
}

template <typename NextLayer>
inline void Connection<NextLayer>::write(const command_wrapper_t &command) {
    boost::system::error_code ec;
    this->write(command, ec);
    if (ec) {
        throw boost::system::system_error{ec};
    }
}

template <typename NextLayer>
template <typename DynamicBuffer>
positive_parse_result_t
Connection<NextLayer>::read(DynamicBuffer &rx_buff,
                            boost::system::error_code &ec) {
    namespace asio = boost::asio;
    using boost::asio::read_until;

    auto rx_bytes = read_until(stream_, rx_buff, MatchResult(1), ec);
    if (ec) {
        return positive_parse_result_t{{}, 0};
    }

    const auto char_ptr =
        boost::asio::buffer_cast<const char *>(rx_buff.data());
    auto size = rx_buff.size();
    string_t data(char_ptr, size);
    BREDIS_LOG_DEBUG("incoming data(" << size << ") : " << char_ptr);

    auto parse_result = Protocol::parse(data);
    auto *parse_error = boost::get<protocol_error_t>(&parse_result);
    if (parse_error) {
        BREDIS_LOG_DEBUG("protocol error: " << parse_error->what);
        ec = Error::make_error_code(bredis_errors::protocol_error);
        return positive_parse_result_t{{}, 0};
    }
    return boost::get<positive_parse_result_t>(parse_result);
}

template <typename NextLayer>
template <typename DynamicBuffer>
inline positive_parse_result_t
Connection<NextLayer>::read(DynamicBuffer &rx_buff) {
    namespace asio = boost::asio;

    boost::system::error_code ec;
    auto result = this->read(rx_buff, ec);
    if (ec) {
        throw boost::system::system_error{ec};
    }
    return result;
}

} // namespace bredis
<|endoftext|>


<commit_before>#include <tree_sitter/parser.h>
#include <vector>
#include <cwctype>
#include <cstring>
#include <cassert>

namespace {

using std::vector;
using std::iswspace;
using std::memcpy;

enum TokenType {
  NEWLINE,
  INDENT,
  DEDENT,
  STRING_START,
  STRING_CONTENT,
  STRING_END,
};

struct Delimiter {
  enum {
    SingleQuote = 1 << 0,
    DoubleQuote = 1 << 1,
    BackQuote = 1 << 2,
    Raw = 1 << 3,
    Format = 1 << 4,
    Triple = 1 << 5,
  };

  Delimiter() : flags(0) {}

  bool is_format() const {
    return flags & Format;
  }

  bool is_raw() const {
    return flags & Raw;
  }

  bool is_triple() const {
    return flags & Triple;
  }

  int32_t end_character() const {
    if (flags & SingleQuote) return '\'';
    if (flags & DoubleQuote) return '"';
    if (flags & BackQuote) return '`';
    return 0;
  }

  void set_format() {
    flags |= Format;
  }

  void set_raw() {
    flags |= Raw;
  }

  void set_triple() {
    flags |= Triple;
  }

  void set_end_character(int32_t character) {
    switch (character) {
      case '\'':
        flags |= SingleQuote;
        break;
      case '"':
        flags |= DoubleQuote;
        break;
      case '`':
        flags |= BackQuote;
        break;
      default:
        assert(false);
    }
  }

  char flags;
};

struct Scanner {
  Scanner() {
    assert(sizeof(Delimiter) == sizeof(char));
    deserialize(NULL, 0);
  }

  unsigned serialize(char *buffer) {
    size_t i = 0;

    buffer[i++] = delimiter_stack.size();
    memcpy(&buffer[i], delimiter_stack.data(), delimiter_stack.size());
    i += delimiter_stack.size();

    vector<uint16_t>::iterator
      iter = indent_length_stack.begin() + 1,
      end = indent_length_stack.end();

    for (; iter != end && i < TREE_SITTER_SERIALIZATION_BUFFER_SIZE; ++iter) {
      buffer[i++] = *iter;
    }

    return i;
  }

  void deserialize(const char *buffer, unsigned length) {
    delimiter_stack.clear();
    indent_length_stack.clear();
    indent_length_stack.push_back(0);

    if (length > 0) {
      size_t i = 0;

      size_t delimiter_count = buffer[i++];
      delimiter_stack.resize(delimiter_count);
      memcpy(delimiter_stack.data(), &buffer[i], delimiter_count);
      i += delimiter_count;

      for (; i < length; i++) {
        indent_length_stack.push_back(buffer[i]);
      }
    }
  }

  void advance(TSLexer *lexer) {
    lexer->advance(lexer, false);
  }

  void skip(TSLexer *lexer) {
    lexer->advance(lexer, true);
  }

  bool scan(TSLexer *lexer, const bool *valid_symbols) {
    if (valid_symbols[STRING_CONTENT] && !valid_symbols[INDENT] && !delimiter_stack.empty()) {
      Delimiter delimiter = delimiter_stack.back();
      int32_t end_character = delimiter.end_character();
      bool has_content = false;
      while (lexer->lookahead) {
        if (lexer->lookahead == '{' && delimiter.is_format()) {
          lexer->mark_end(lexer);
          lexer->advance(lexer, false);
          if (lexer->lookahead == '{') {
            lexer->advance(lexer, false);
          } else {
            lexer->result_symbol = STRING_CONTENT;
            return has_content;
          }
        } else if (lexer->lookahead == '\\') {
          if (delimiter.is_raw()) {
            lexer->advance(lexer, false);
          } else {
            lexer->mark_end(lexer);
            lexer->result_symbol = STRING_CONTENT;
            return has_content;
          }
        } else if (lexer->lookahead == end_character) {
          if (delimiter.is_triple()) {
            lexer->mark_end(lexer);
            lexer->advance(lexer, false);
            if (lexer->lookahead == end_character) {
              lexer->advance(lexer, false);
              if (lexer->lookahead == end_character) {
                if (has_content) {
                  lexer->result_symbol = STRING_CONTENT;
                } else {
                  lexer->advance(lexer, false);
                  lexer->mark_end(lexer);
                  delimiter_stack.pop_back();
                  lexer->result_symbol = STRING_END;
                }
                return true;
              }
            }
          } else {
            if (has_content) {
              lexer->result_symbol = STRING_CONTENT;
            } else {
              lexer->advance(lexer, false);
              delimiter_stack.pop_back();
              lexer->result_symbol = STRING_END;
            }
            lexer->mark_end(lexer);
            return true;
          }
        } else if (lexer->lookahead == '\n' && has_content && !delimiter.is_triple()) {
          return false;
        }
        advance(lexer);
        has_content = true;
      }
    }

    lexer->mark_end(lexer);

    bool has_comment = false;
    bool has_newline = false;
    uint32_t indent_length = 0;
    for (;;) {
      if (lexer->lookahead == '\n') {
        has_newline = true;
        indent_length = 0;
        skip(lexer);
      } else if (lexer->lookahead == ' ') {
        indent_length++;
        skip(lexer);
      } else if (lexer->lookahead == '\r') {
        indent_length = 0;
        skip(lexer);
      } else if (lexer->lookahead == '\t') {
        indent_length += 8;
        skip(lexer);
      } else if (lexer->lookahead == '#') {
        has_comment = true;
        while (lexer->lookahead && lexer->lookahead != '\n') skip(lexer);
        skip(lexer);
        indent_length = 0;
      } else if (lexer->lookahead == '\\') {
        skip(lexer);
        if (iswspace(lexer->lookahead)) {
          skip(lexer);
        } else {
          return false;
        }
      } else if (lexer->lookahead == 0) {
        if (valid_symbols[DEDENT] && indent_length_stack.size() > 1) {
          indent_length_stack.pop_back();
          lexer->result_symbol = DEDENT;
          return true;
        }

        if (valid_symbols[NEWLINE]) {
          lexer->result_symbol = NEWLINE;
          return true;
        }

        break;
      } else {
        break;
      }
    }

    if (has_newline) {
      if (indent_length > indent_length_stack.back() && valid_symbols[INDENT]) {
        indent_length_stack.push_back(indent_length);
        lexer->result_symbol = INDENT;
        return true;
      }

      if (indent_length < indent_length_stack.back() && valid_symbols[DEDENT]) {
        indent_length_stack.pop_back();
        lexer->result_symbol = DEDENT;
        return true;
      }

      if (valid_symbols[NEWLINE]) {
        lexer->result_symbol = NEWLINE;
        return true;
      }
    }

    if (!has_comment && valid_symbols[STRING_START]) {
      Delimiter delimiter;

      bool has_flags = false;
      while (lexer->lookahead) {
        if (lexer->lookahead == 'f' || lexer->lookahead == 'F') {
          delimiter.set_format();
        } else if (lexer->lookahead == 'r' || lexer->lookahead == 'R') {
          delimiter.set_raw();
        } else if (
          lexer->lookahead != 'b' &&
          lexer->lookahead != 'B' &&
          lexer->lookahead != 'u' &&
          lexer->lookahead != 'U') {
          break;
        }
        has_flags = true;
        advance(lexer);
      }

      if (lexer->lookahead == '`') {
        delimiter.set_end_character('`');
        advance(lexer);
        lexer->mark_end(lexer);
      } else if (lexer->lookahead == '\'') {
        delimiter.set_end_character('\'');
        advance(lexer);
        lexer->mark_end(lexer);
        if (lexer->lookahead == '\'') {
          advance(lexer);
          if (lexer->lookahead == '\'') {
            advance(lexer);
            lexer->mark_end(lexer);
            delimiter.set_triple();
          }
        }
      } else if (lexer->lookahead == '"') {
        delimiter.set_end_character('"');
        advance(lexer);
        lexer->mark_end(lexer);
        if (lexer->lookahead == '"') {
          advance(lexer);
          if (lexer->lookahead == '"') {
            advance(lexer);
            lexer->mark_end(lexer);
            delimiter.set_triple();
          }
        }
      }

      if (delimiter.end_character()) {
        delimiter_stack.push_back(delimiter);
        lexer->result_symbol = STRING_START;
        return true;
      } else if (has_flags) {
        return false;
      }
    }

    return false;
  }

  vector<uint16_t> indent_length_stack;
  vector<Delimiter> delimiter_stack;
};

}

extern "C" {

void *tree_sitter_python_external_scanner_create() {
  return new Scanner();
}

bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer,
                                            const bool *valid_symbols) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  return scanner->scan(lexer, valid_symbols);
}

unsigned tree_sitter_python_external_scanner_serialize(void *payload, char *buffer) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  return scanner->serialize(buffer);
}

void tree_sitter_python_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  scanner->deserialize(buffer, length);
}

void tree_sitter_python_external_scanner_destroy(void *payload) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  delete scanner;
}

}
<commit_msg>Fix integer overflow in external scanner<commit_after>#include <tree_sitter/parser.h>
#include <vector>
#include <cwctype>
#include <cstring>
#include <cassert>

namespace {

using std::vector;
using std::iswspace;
using std::memcpy;

enum TokenType {
  NEWLINE,
  INDENT,
  DEDENT,
  STRING_START,
  STRING_CONTENT,
  STRING_END,
};

struct Delimiter {
  enum {
    SingleQuote = 1 << 0,
    DoubleQuote = 1 << 1,
    BackQuote = 1 << 2,
    Raw = 1 << 3,
    Format = 1 << 4,
    Triple = 1 << 5,
  };

  Delimiter() : flags(0) {}

  bool is_format() const {
    return flags & Format;
  }

  bool is_raw() const {
    return flags & Raw;
  }

  bool is_triple() const {
    return flags & Triple;
  }

  int32_t end_character() const {
    if (flags & SingleQuote) return '\'';
    if (flags & DoubleQuote) return '"';
    if (flags & BackQuote) return '`';
    return 0;
  }

  void set_format() {
    flags |= Format;
  }

  void set_raw() {
    flags |= Raw;
  }

  void set_triple() {
    flags |= Triple;
  }

  void set_end_character(int32_t character) {
    switch (character) {
      case '\'':
        flags |= SingleQuote;
        break;
      case '"':
        flags |= DoubleQuote;
        break;
      case '`':
        flags |= BackQuote;
        break;
      default:
        assert(false);
    }
  }

  char flags;
};

struct Scanner {
  Scanner() {
    assert(sizeof(Delimiter) == sizeof(char));
    deserialize(NULL, 0);
  }

  unsigned serialize(char *buffer) {
    size_t i = 0;

    size_t stack_size = delimiter_stack.size();
    if (stack_size > UINT8_MAX) stack_size = UINT8_MAX;
    buffer[i++] = stack_size;

    memcpy(&buffer[i], delimiter_stack.data(), stack_size);
    i += stack_size;

    vector<uint16_t>::iterator
      iter = indent_length_stack.begin() + 1,
      end = indent_length_stack.end();

    for (; iter != end && i < TREE_SITTER_SERIALIZATION_BUFFER_SIZE; ++iter) {
      buffer[i++] = *iter;
    }

    return i;
  }

  void deserialize(const char *buffer, unsigned length) {
    delimiter_stack.clear();
    indent_length_stack.clear();
    indent_length_stack.push_back(0);

    if (length > 0) {
      size_t i = 0;

      size_t delimiter_count = (uint8_t)buffer[i++];
      delimiter_stack.resize(delimiter_count);
      memcpy(delimiter_stack.data(), &buffer[i], delimiter_count);
      i += delimiter_count;

      for (; i < length; i++) {
        indent_length_stack.push_back(buffer[i]);
      }
    }
  }

  void advance(TSLexer *lexer) {
    lexer->advance(lexer, false);
  }

  void skip(TSLexer *lexer) {
    lexer->advance(lexer, true);
  }

  bool scan(TSLexer *lexer, const bool *valid_symbols) {
    if (valid_symbols[STRING_CONTENT] && !valid_symbols[INDENT] && !delimiter_stack.empty()) {
      Delimiter delimiter = delimiter_stack.back();
      int32_t end_character = delimiter.end_character();
      bool has_content = false;
      while (lexer->lookahead) {
        if (lexer->lookahead == '{' && delimiter.is_format()) {
          lexer->mark_end(lexer);
          lexer->advance(lexer, false);
          if (lexer->lookahead == '{') {
            lexer->advance(lexer, false);
          } else {
            lexer->result_symbol = STRING_CONTENT;
            return has_content;
          }
        } else if (lexer->lookahead == '\\') {
          if (delimiter.is_raw()) {
            lexer->advance(lexer, false);
          } else {
            lexer->mark_end(lexer);
            lexer->result_symbol = STRING_CONTENT;
            return has_content;
          }
        } else if (lexer->lookahead == end_character) {
          if (delimiter.is_triple()) {
            lexer->mark_end(lexer);
            lexer->advance(lexer, false);
            if (lexer->lookahead == end_character) {
              lexer->advance(lexer, false);
              if (lexer->lookahead == end_character) {
                if (has_content) {
                  lexer->result_symbol = STRING_CONTENT;
                } else {
                  lexer->advance(lexer, false);
                  lexer->mark_end(lexer);
                  delimiter_stack.pop_back();
                  lexer->result_symbol = STRING_END;
                }
                return true;
              }
            }
          } else {
            if (has_content) {
              lexer->result_symbol = STRING_CONTENT;
            } else {
              lexer->advance(lexer, false);
              delimiter_stack.pop_back();
              lexer->result_symbol = STRING_END;
            }
            lexer->mark_end(lexer);
            return true;
          }
        } else if (lexer->lookahead == '\n' && has_content && !delimiter.is_triple()) {
          return false;
        }
        advance(lexer);
        has_content = true;
      }
    }

    lexer->mark_end(lexer);

    bool has_comment = false;
    bool has_newline = false;
    uint32_t indent_length = 0;
    for (;;) {
      if (lexer->lookahead == '\n') {
        has_newline = true;
        indent_length = 0;
        skip(lexer);
      } else if (lexer->lookahead == ' ') {
        indent_length++;
        skip(lexer);
      } else if (lexer->lookahead == '\r') {
        indent_length = 0;
        skip(lexer);
      } else if (lexer->lookahead == '\t') {
        indent_length += 8;
        skip(lexer);
      } else if (lexer->lookahead == '#') {
        has_comment = true;
        while (lexer->lookahead && lexer->lookahead != '\n') skip(lexer);
        skip(lexer);
        indent_length = 0;
      } else if (lexer->lookahead == '\\') {
        skip(lexer);
        if (iswspace(lexer->lookahead)) {
          skip(lexer);
        } else {
          return false;
        }
      } else if (lexer->lookahead == 0) {
        if (valid_symbols[DEDENT] && indent_length_stack.size() > 1) {
          indent_length_stack.pop_back();
          lexer->result_symbol = DEDENT;
          return true;
        }

        if (valid_symbols[NEWLINE]) {
          lexer->result_symbol = NEWLINE;
          return true;
        }

        break;
      } else {
        break;
      }
    }

    if (has_newline) {
      if (indent_length > indent_length_stack.back() && valid_symbols[INDENT]) {
        indent_length_stack.push_back(indent_length);
        lexer->result_symbol = INDENT;
        return true;
      }

      if (indent_length < indent_length_stack.back() && valid_symbols[DEDENT]) {
        indent_length_stack.pop_back();
        lexer->result_symbol = DEDENT;
        return true;
      }

      if (valid_symbols[NEWLINE]) {
        lexer->result_symbol = NEWLINE;
        return true;
      }
    }

    if (!has_comment && valid_symbols[STRING_START]) {
      Delimiter delimiter;

      bool has_flags = false;
      while (lexer->lookahead) {
        if (lexer->lookahead == 'f' || lexer->lookahead == 'F') {
          delimiter.set_format();
        } else if (lexer->lookahead == 'r' || lexer->lookahead == 'R') {
          delimiter.set_raw();
        } else if (
          lexer->lookahead != 'b' &&
          lexer->lookahead != 'B' &&
          lexer->lookahead != 'u' &&
          lexer->lookahead != 'U') {
          break;
        }
        has_flags = true;
        advance(lexer);
      }

      if (lexer->lookahead == '`') {
        delimiter.set_end_character('`');
        advance(lexer);
        lexer->mark_end(lexer);
      } else if (lexer->lookahead == '\'') {
        delimiter.set_end_character('\'');
        advance(lexer);
        lexer->mark_end(lexer);
        if (lexer->lookahead == '\'') {
          advance(lexer);
          if (lexer->lookahead == '\'') {
            advance(lexer);
            lexer->mark_end(lexer);
            delimiter.set_triple();
          }
        }
      } else if (lexer->lookahead == '"') {
        delimiter.set_end_character('"');
        advance(lexer);
        lexer->mark_end(lexer);
        if (lexer->lookahead == '"') {
          advance(lexer);
          if (lexer->lookahead == '"') {
            advance(lexer);
            lexer->mark_end(lexer);
            delimiter.set_triple();
          }
        }
      }

      if (delimiter.end_character()) {
        delimiter_stack.push_back(delimiter);
        lexer->result_symbol = STRING_START;
        return true;
      } else if (has_flags) {
        return false;
      }
    }

    return false;
  }

  vector<uint16_t> indent_length_stack;
  vector<Delimiter> delimiter_stack;
};

}

extern "C" {

void *tree_sitter_python_external_scanner_create() {
  return new Scanner();
}

bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer,
                                            const bool *valid_symbols) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  return scanner->scan(lexer, valid_symbols);
}

unsigned tree_sitter_python_external_scanner_serialize(void *payload, char *buffer) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  return scanner->serialize(buffer);
}

void tree_sitter_python_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  scanner->deserialize(buffer, length);
}

void tree_sitter_python_external_scanner_destroy(void *payload) {
  Scanner *scanner = static_cast<Scanner *>(payload);
  delete scanner;
}

}
<|endoftext|>


<commit_before>/*
 * OptionDefinition.hpp
 *
 *  Created on: 04/05/2011
 *        User: diego
 *      Author: Diego Lago <diego.lago.gonzalez@gmail.com>
 */

#ifndef OPTIONDEFINITION_HPP_
#define OPTIONDEFINITION_HPP_

#include <list>
#include <set>

namespace clipp {

/**
 * Lista y set de cadenas.
 */
typedef std::set<string>		StringSet;

/**
 * Declaración de la clase que contiene estas clases.
 */
class OptionManager;
class Option;

/**
 * Tipo de función que se ejecutará cuando se procesen las opciones.
 *
 * @param Option* option La opción procesada.
 * @return int Resultado.
 */
typedef int (*OnOptionProcessed)(const Option* option);

/**
 * Definición de una opción.
 */
class OptionDefinition {
	public:

		/**
		 * Tipo del valor del argumento de la opción.
		 */
		enum OptionType {
			TypeNone,
			TypeString,
			TypeInteger,
			TypeFloat,
			TypeBoolean
		};

	private:
		OptionManager*		fOwner;				/// Puntero al OpcionManager que tiene esta instancia.
		int					fId;				/// El id numérico de la opción.
		string				fName;				/// Nombre de la opción.
		OptionType			fType;				/// Tipo de la opción.
		string				fDescription;		/// Descripción de la opción.
		bool				fHidden;			/// Si está oculta.
		bool				fRequired;			/// Si es obligatoria.
		bool				fHasArgument;		/// Si tiene argumento.
		bool				fArgumentRequired;	/// Si el argumento es obligatorio.
		bool				fMultiple;			/// Si es múltiple.
		bool				fExclusive;			/// Si es exclusiva.
		bool				fAllowNoPreffix;	/// Si permite prefijo "no-" en opciones.
		string				fAlias;				/// Si tiene un alias (sólo uno).
		StringSet			fValidStrings;		/// Cadenas válidas para su argumento.
		StringSet			fConflictsWith;		/// Opciones con las que tiene conflicto (no pueden estar juntas).
		bool				fHasMinValue;		/// Si tiene valor mínimo si es numérico el argumento.
		float				fMinValue;			/// Valor mínimo.
		bool				fHasMaxValue;		/// Si tiene valor máximo.
		float				fMaxValue;			/// Valor máximo.
		bool				fHasDefaultValue;	/// Indica si tiene valor predeterminado o no.
		string				fDefaultValue;		/// Valor predeterminado de esta opción.
		OnOptionProcessed	fExecute;			/// Función ejecutada cuando se analizan todas las opciones.
		void*				fVar;				/// Pointer to variable to be updated.

		/**
		 * Clase amiga que puede acceder a las propiedades de esta clase.
		 */
		friend class	OptionManager;

		/**
		 * Si la opción es exclusiva no puede ser múltiple ni obligatoria.
		 * Se lanza excepción en caso de que se produzca.
		 *
		 * @throw OptionDefinitionException Si hay error en la opción.
		 */
		void			checkExclusivity() const;

		/**
		 * Clase que puede acceder a las siguientes funciones privadas.
		 */
		friend class	Option;

		/**
		 * Comprueba el tipo de argumento.
		 *
		 * @param string argument El argumento a comprobar.
		 * @throw clipp::Exception En caso de fallo.
		 */
		void			checkArgumentType(const string argument) const;

		/**
		 * Comprueba el valor del argrumento (rango y valores de cadena).
		 *
		 * @param string value Valor a comprobar.
		 * @throw clipp::Exception En caso de fallo.
		 */
		void			checkArgumentValue(const string value) const;

		OptionDefinition&	var(void* value, OptionType type);

	public:

		/**
		 * Constructor de copia de la clase.
		 *
		 * @param OptionDefinition& od OptionDefintion a copiar.
		 */
		OptionDefinition(const OptionDefinition& od);

		/**
		 * Constructor de la clase.
		 *
		 * @param string name Nombre de la opción.
		 * @param OptionType type Tipo de la opción.
		 * @param string description Descripción.
		 */
		OptionDefinition(const string name, OptionType type = TypeString, const string description = string());

		/**
		 * Constructor de la clase.
		 *
		 * @param int id Id de la opción.
		 * @param string name Nombre de la opción.
		 * @param OptionType type Tipo de la opción.
		 * @param string description Descripción.
		 */
		OptionDefinition(int id, const string name, OptionType type = TypeString, const string description = string());

		/**
		 * Destructor de la clase.
		 */
		virtual 			~OptionDefinition();

		/**
		 * Operador de comparación de igualdad.
		 *
		 * @param OptionDefinition/string od Opción a comparar.
		 * @return bool True si son iguales, false en otro caso.
		 */
		bool				operator == (const OptionDefinition& od) const;
		bool				operator == (const string on) const;

		/**
		 * Operador de comparación de desigualdad.
		 *
		 * @param OptionDefinition/string od Opción a comparar.
		 * @return bool True si son distintos, false en otro caso.
		 */
		bool				operator != (const OptionDefinition& od) const;
		bool				operator != (const string on) const;

		/**
		 * Fija y devuelve el ID de la opción.
		 *
		 * @param int id ID.
		 * @return int ID.
		 */
		OptionDefinition&	id(int id);
		int					id() const;

		/**
		 * Fija y devuelve el nombre de la opción.
		 *
		 * @param string name Nombre de la opción.
		 * @return string Nombre de la opción.
		 */
		OptionDefinition&	name(const string name);
		const string		name() const;

		/**
		 * Fija y devuelve el tipo de la opción.
		 *
		 * @param OptionType ot Tipo de la opción.
		 * @return OptionDefinition& *this
		 * @return OptionType Tipo de la opción.
		 */
		OptionDefinition&	type(OptionType ot);
		OptionType			type() const;

		/**
		 * Devuelve si es una opción larga o corta.
		 *
		 * @return bool True si se cumple la propiedad.
		 */
		bool				isLongOption() const;
		bool				isShortOption() const;

		/**
		 * Fija el tipo de la opción. Similar a "type(...)" pero con los
		 * parámetros ya definidos.
		 *
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	typeString();
		OptionDefinition&	typeInteger();
		OptionDefinition&	typeFloat();
		OptionDefinition&	typeBool();

		/**
		 * Fija un puntero a la variable que será actualizada con esta opción.
		 *
		 * @param [type]* Puntero a la variable.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	var(string* value);
		OptionDefinition&	var(char** value);
		OptionDefinition&	var(int* value);
		OptionDefinition&	var(float* value);
		OptionDefinition&	var(double* value);
		OptionDefinition&	var(bool* value);

		/**
		 * Devuelve el puntero a la variable a ser actualizada, pero no el tipo.
		 */
		void*				var() const;

		/**
		 * Devuelve un puntero a la variable a actualizar pero con un casting
		 * hecho a su tipo (según la plantilla).
		 */
		template <typename T>
		T*					var() const { return static_cast<T*>(var()); };

		/**
		 * Devuelve si tiene variable asignada o no.
		 */
		bool				hasVar() const;

		/**
		 * Fija un alias, comprueba que el alias existe y devuelve el alias.
		 *
		 * @param string alias Alias.
		 * @return OptionDefinition& *this
		 * @return string Alias.
		 */
		OptionDefinition&	alias(const string alias);
		bool				hasAlias() const;
		const string		alias() const;

		/**
		 * Fija y devuelve la descripción de la opción.
		 *
		 * @param string description Descripción.
		 * @return OptionDefinition& *this
		 * @return string Descripción.
		 */
		OptionDefinition&	description(const string description);
		const string		description() const;

		/**
		 * Fija y devuelve si la opción está oculta.
		 *
		 * @param bool hidden True para ocultarla.
		 * @return bool True si está oculta.
		 */
		void				hidden(bool hidden);
		bool				hidden() const;

		/**
		 * Fija y devuelve si es obligatoria.
		 *
		 * @param bool value True si es obligatoria.
		 * @return OptionDefinition& *this
		 * @return bool True si es obligatoria.
		 */
		OptionDefinition&	required(bool required = true);
		bool				isRequired() const;

		/**
		 * Fija y devuelve si una opción es requerida sólo si ya existe una
		 * opción indicada. Este método se puede invocar varias veces.
		 *
		 * @param string option La opción requerida para que esta lo sea.
		 * @return OptionDefinition& this
		 * @return bool True si esta opción es requerida ante la pasada
		 * como parámetro.
		 */
		OptionDefinition&	requiredIfOption(const string option);
		bool				isRequiredIfOption(const string option) const;

		/**
		 * Fija y devuelve si una opción NO es requerida sólo si ya existe una
		 * opción indicada. Este método se puede invocar varias veces.
		 *
		 * @param string option La opción requerida para que esta lo sea.
		 * @return OptionDefinition& this
		 * @return bool True si esta opción NO es requerida ante la pasada
		 * como parámetro.
		 */
		OptionDefinition&	requiredIfNotOption(const string option);
		bool				isRequiredIfNotOption(const string option) const;

		/**
		 * Fija y devuelve las opciones con las que tiene conflicto (no pueden
		 * estar juntas).
		 *
		 * @param StringSet conflicts Lista de opciones con las que tiene
		 * conflicto.
		 * @return OptionDefinition& this
		 * @return StringSet& Lista de opciones con conflicto (referencia).
		 */
		OptionDefinition&	conflictsWith(const string conflicts);
		OptionDefinition&	conflictsWith(StringSet conflicts);
		StringSet			conflictsWith() const;

		/**
		 * Fija y devuelve si esta opción tiene argumento.
		 *
		 * @param bool value True si tiene argumento.
		 * @param bool required True si el argumento es obligatorio.
		 * @return OptionDefinition& *this
		 * @return bool True si tiene argumento.
		 */
		OptionDefinition&	argument(bool has = true, bool required = false);
		bool				hasArgument() const;

		/**
		 * Fija y devuelve si el argumento de esta opción es obligatorio.
		 *
		 * @param bool value True si el argumento es obligatorio.
		 * @return OptionDefinition& *this
		 * @return bool True si el argumento es obligatorio.
		 */
		OptionDefinition&	argumentRequired(bool required = true);
		bool				isArgumentRequired() const;

		/**
		 * Fija y devuelve si la opción es múltiple.
		 *
		 * @param bool value True si es múltiple.
		 * @return OptionDefinition& *this
		 * @return bool True si es múltiple.
		 */
		OptionDefinition&	multiple(bool multiple = true);
		bool				isMultiple() const;

		/**
		 * Fija y devuelve si la opción es exclusiva.
		 *
		 * @param bool value True si es exclusiva.
		 * @return OptionDefinition& *this
		 * @return bool True si es exclusiva.
		 */
		OptionDefinition&	exclusive(bool exclusive = true);
		bool				isExclusive() const;

		/**
		 * Permite opciones tal que --option y --no-option.
		 *
		 * @param bool allow True para permitir, false en otro caso.
		 * @return OptionDefinition& *this
		 * @return bool True si se permite el prefijo.
		 */
		OptionDefinition&	allowNoPreffix(bool allow = true);
		bool				allowNoPreffix() const;

		/**
		 * Fija y devuelve el valor predeterminado de esta opción.
		 *
		 * @param string defaultValue Valor por defecto.
		 * @return string Valor por defecto.
		 */
		void				defaultValue(const string defaultValue);
		const string		defaultValue() const;

		/**
		 * Elimina el valor predeterminado.
		 */
		void				removeDefaultValue();

		/**
		 * Indica si el valor predeterminado está fijado o no.
		 *
		 * @return bool True si está fijado, false en otro caso.
		 */
		bool				hasDefaultValue() const;

		/**
		 * Fija y devuelve un puntero a la función que hay que ejecutar
		 * cuando se procese esta opción.
		 *
		 * @param OnOptionProcessed executeThis Puntero a la función a
		 * ejecutar.
		 * @return OnOptionProcessed Puntero a la función a ejecutar.
		 */
		void				execute(OnOptionProcessed executeThis);
		OnOptionProcessed	execute() const;

		/**
		 * Fija las cadenas válidas para esta opción.
		 *
		 * @param string validString Cadena válida.
		 * @param StringSet validStrings Cadenas válidas.
		 * @param string[] validStrings Cadenas válidas.
		 * @param int length Longitud del array de cadenas válidas.
		 * @return OptionDefinition& *this
		 * @return StringSet Cadenas válidas.
		 */
		OptionDefinition&	validString(const string validString);
		OptionDefinition&	validStrings(const StringSet validStrings);
		OptionDefinition&	validStrings(const string validStrings[], int length);
		StringSet			validStrings() const;

		/**
		 * Devuelve si esta opción tiene valor mínimo en caso de que su
		 * argumento sea numérico.
		 *
		 * @param float& value Devuelve el valor mínimo en caso de que tenga
		 * valor mínimo.
		 * @return bool True si tiene valor mínimo, false en otro caso.
		 */
		bool				hasMinValue(float& value) const;

		/**
		 * Fija el valor mínimo.
		 *
		 * @param float value Valor mínimo.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	minValue(float value);

		/**
		 * Devuelve si esta opción tiene valor máximo en caso de que su
		 * argumento sea numérico.
		 *
		 * @param float& value Devuelve el valor máximo en caso de que tenga
		 * valor máximo.
		 * @return bool True si tiene valor máximo, false en otro caso.
		 */
		bool				hasMaxValue(float& value) const;

		/**
		 * Fija el valor máximo.
		 *
		 * @param float value Valor máximo.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	maxValue(float value);
};

}	// namespace clipp

#endif /* OPTIONDEFINITION_HPP_ */
<commit_msg>Documentation.<commit_after>/*
 * OptionDefinition.hpp
 *
 *  Created on: 04/05/2011
 *        User: diego
 *      Author: Diego Lago <diego.lago.gonzalez@gmail.com>
 */

#ifndef OPTIONDEFINITION_HPP_
#define OPTIONDEFINITION_HPP_

#include <list>
#include <set>

namespace clipp {

/**
 * Lista y set de cadenas.
 */
typedef std::set<string>		StringSet;

/**
 * Declaración de la clase que contiene estas clases.
 */
class OptionManager;
class Option;

/**
 * Tipo de función que se ejecutará cuando se procesen las opciones.
 *
 * @param Option* option La opción procesada.
 * @return int Resultado.
 */
typedef int (*OnOptionProcessed)(const Option* option);

/**
 * Definición de una opción.
 */
class OptionDefinition {
	public:

		/**
		 * Tipo del valor del argumento de la opción.
		 */
		enum OptionType {
			TypeNone,
			TypeString,
			TypeInteger,
			TypeFloat,
			TypeBoolean
		};

	private:
		OptionManager*		fOwner;				/// Puntero al OpcionManager que tiene esta instancia.
		int					fId;				/// El id numérico de la opción.
		string				fName;				/// Nombre de la opción.
		OptionType			fType;				/// Tipo de la opción.
		string				fDescription;		/// Descripción de la opción.
		bool				fHidden;			/// Si está oculta.
		bool				fRequired;			/// Si es obligatoria.
		bool				fHasArgument;		/// Si tiene argumento.
		bool				fArgumentRequired;	/// Si el argumento es obligatorio.
		bool				fMultiple;			/// Si es múltiple.
		bool				fExclusive;			/// Si es exclusiva.
		bool				fAllowNoPreffix;	/// Si permite prefijo "no-" en opciones.
		string				fAlias;				/// Si tiene un alias (sólo uno).
		StringSet			fValidStrings;		/// Cadenas válidas para su argumento.
		StringSet			fConflictsWith;		/// Opciones con las que tiene conflicto (no pueden estar juntas).
		bool				fHasMinValue;		/// Si tiene valor mínimo si es numérico el argumento.
		float				fMinValue;			/// Valor mínimo.
		bool				fHasMaxValue;		/// Si tiene valor máximo.
		float				fMaxValue;			/// Valor máximo.
		bool				fHasDefaultValue;	/// Indica si tiene valor predeterminado o no.
		string				fDefaultValue;		/// Valor predeterminado de esta opción.
		OnOptionProcessed	fExecute;			/// Función ejecutada cuando se analizan todas las opciones.
		void*				fVar;				/// Pointer to variable to be updated.

		/**
		 * Clase amiga que puede acceder a las propiedades de esta clase.
		 */
		friend class		OptionManager;

		/**
		 * Si la opción es exclusiva no puede ser múltiple ni obligatoria.
		 * Se lanza excepción en caso de que se produzca.
		 *
		 * @throw OptionDefinitionException Si hay error en la opción.
		 */
		void				checkExclusivity() const;

		/**
		 * Clase que puede acceder a las siguientes funciones privadas.
		 */
		friend class		Option;

		/**
		 * Comprueba el tipo de argumento.
		 *
		 * @param string argument El argumento a comprobar.
		 * @throw clipp::Exception En caso de fallo.
		 */
		void				checkArgumentType(const string argument) const;

		/**
		 * Comprueba el valor del argrumento (rango y valores de cadena).
		 *
		 * @param string value Valor a comprobar.
		 * @throw clipp::Exception En caso de fallo.
		 */
		void				checkArgumentValue(const string value) const;

		/**
		 * Asigna un puntero a una variable y su tipo.
		 *
		 * @param void* value Puntero a la variable.
		 * @param OptionType Tipo de la variable.
		 * @return OptionDefinition& this
		 */
		OptionDefinition&	var(void* value, OptionType type);

	public:

		/**
		 * Constructor de copia de la clase.
		 *
		 * @param OptionDefinition& od OptionDefintion a copiar.
		 */
		OptionDefinition(const OptionDefinition& od);

		/**
		 * Constructor de la clase.
		 *
		 * @param string name Nombre de la opción.
		 * @param OptionType type Tipo de la opción.
		 * @param string description Descripción.
		 */
		OptionDefinition(const string name, OptionType type = TypeString, const string description = string());

		/**
		 * Constructor de la clase.
		 *
		 * @param int id Id de la opción.
		 * @param string name Nombre de la opción.
		 * @param OptionType type Tipo de la opción.
		 * @param string description Descripción.
		 */
		OptionDefinition(int id, const string name, OptionType type = TypeString, const string description = string());

		/**
		 * Destructor de la clase.
		 */
		virtual 			~OptionDefinition();

		/**
		 * Operador de comparación de igualdad.
		 *
		 * @param OptionDefinition/string od Opción a comparar.
		 * @return bool True si son iguales, false en otro caso.
		 */
		bool				operator == (const OptionDefinition& od) const;
		bool				operator == (const string on) const;

		/**
		 * Operador de comparación de desigualdad.
		 *
		 * @param OptionDefinition/string od Opción a comparar.
		 * @return bool True si son distintos, false en otro caso.
		 */
		bool				operator != (const OptionDefinition& od) const;
		bool				operator != (const string on) const;

		/**
		 * Fija y devuelve el ID de la opción.
		 *
		 * @param int id ID.
		 * @return int ID.
		 */
		OptionDefinition&	id(int id);
		int					id() const;

		/**
		 * Fija y devuelve el nombre de la opción.
		 *
		 * @param string name Nombre de la opción.
		 * @return string Nombre de la opción.
		 */
		OptionDefinition&	name(const string name);
		const string		name() const;

		/**
		 * Fija y devuelve el tipo de la opción.
		 *
		 * @param OptionType ot Tipo de la opción.
		 * @return OptionDefinition& *this
		 * @return OptionType Tipo de la opción.
		 */
		OptionDefinition&	type(OptionType ot);
		OptionType			type() const;

		/**
		 * Devuelve si es una opción larga o corta.
		 *
		 * @return bool True si se cumple la propiedad.
		 */
		bool				isLongOption() const;
		bool				isShortOption() const;

		/**
		 * Fija el tipo de la opción. Similar a "type(...)" pero con los
		 * parámetros ya definidos.
		 *
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	typeString();
		OptionDefinition&	typeInteger();
		OptionDefinition&	typeFloat();
		OptionDefinition&	typeBool();

		/**
		 * Fija un puntero a la variable que será actualizada con esta opción.
		 *
		 * @param [type]* Puntero a la variable.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	var(string* value);
		OptionDefinition&	var(char** value);
		OptionDefinition&	var(int* value);
		OptionDefinition&	var(float* value);
		OptionDefinition&	var(double* value);
		OptionDefinition&	var(bool* value);

		/**
		 * Devuelve el puntero a la variable a ser actualizada, pero no el tipo.
		 */
		void*				var() const;

		/**
		 * Devuelve un puntero a la variable a actualizar pero con un casting
		 * hecho a su tipo (según la plantilla).
		 */
		template <typename T>
		T*					var() const { return static_cast<T*>(var()); };

		/**
		 * Devuelve si tiene variable asignada o no.
		 */
		bool				hasVar() const;

		/**
		 * Fija un alias, comprueba que el alias existe y devuelve el alias.
		 *
		 * @param string alias Alias.
		 * @return OptionDefinition& *this
		 * @return string Alias.
		 */
		OptionDefinition&	alias(const string alias);
		bool				hasAlias() const;
		const string		alias() const;

		/**
		 * Fija y devuelve la descripción de la opción.
		 *
		 * @param string description Descripción.
		 * @return OptionDefinition& *this
		 * @return string Descripción.
		 */
		OptionDefinition&	description(const string description);
		const string		description() const;

		/**
		 * Fija y devuelve si la opción está oculta.
		 *
		 * @param bool hidden True para ocultarla.
		 * @return bool True si está oculta.
		 */
		void				hidden(bool hidden);
		bool				hidden() const;

		/**
		 * Fija y devuelve si es obligatoria.
		 *
		 * @param bool value True si es obligatoria.
		 * @return OptionDefinition& *this
		 * @return bool True si es obligatoria.
		 */
		OptionDefinition&	required(bool required = true);
		bool				isRequired() const;

		/**
		 * Fija y devuelve si una opción es requerida sólo si ya existe una
		 * opción indicada. Este método se puede invocar varias veces.
		 *
		 * @param string option La opción requerida para que esta lo sea.
		 * @return OptionDefinition& this
		 * @return bool True si esta opción es requerida ante la pasada
		 * como parámetro.
		 */
		OptionDefinition&	requiredIfOption(const string option);
		bool				isRequiredIfOption(const string option) const;

		/**
		 * Fija y devuelve si una opción NO es requerida sólo si ya existe una
		 * opción indicada. Este método se puede invocar varias veces.
		 *
		 * @param string option La opción requerida para que esta lo sea.
		 * @return OptionDefinition& this
		 * @return bool True si esta opción NO es requerida ante la pasada
		 * como parámetro.
		 */
		OptionDefinition&	requiredIfNotOption(const string option);
		bool				isRequiredIfNotOption(const string option) const;

		/**
		 * Fija y devuelve las opciones con las que tiene conflicto (no pueden
		 * estar juntas).
		 *
		 * @param StringSet conflicts Lista de opciones con las que tiene
		 * conflicto.
		 * @return OptionDefinition& this
		 * @return StringSet& Lista de opciones con conflicto (referencia).
		 */
		OptionDefinition&	conflictsWith(const string conflicts);
		OptionDefinition&	conflictsWith(StringSet conflicts);
		StringSet			conflictsWith() const;

		/**
		 * Fija y devuelve si esta opción tiene argumento.
		 *
		 * @param bool value True si tiene argumento.
		 * @param bool required True si el argumento es obligatorio.
		 * @return OptionDefinition& *this
		 * @return bool True si tiene argumento.
		 */
		OptionDefinition&	argument(bool has = true, bool required = false);
		bool				hasArgument() const;

		/**
		 * Fija y devuelve si el argumento de esta opción es obligatorio.
		 *
		 * @param bool value True si el argumento es obligatorio.
		 * @return OptionDefinition& *this
		 * @return bool True si el argumento es obligatorio.
		 */
		OptionDefinition&	argumentRequired(bool required = true);
		bool				isArgumentRequired() const;

		/**
		 * Fija y devuelve si la opción es múltiple.
		 *
		 * @param bool value True si es múltiple.
		 * @return OptionDefinition& *this
		 * @return bool True si es múltiple.
		 */
		OptionDefinition&	multiple(bool multiple = true);
		bool				isMultiple() const;

		/**
		 * Fija y devuelve si la opción es exclusiva.
		 *
		 * @param bool value True si es exclusiva.
		 * @return OptionDefinition& *this
		 * @return bool True si es exclusiva.
		 */
		OptionDefinition&	exclusive(bool exclusive = true);
		bool				isExclusive() const;

		/**
		 * Permite opciones tal que --option y --no-option.
		 *
		 * @param bool allow True para permitir, false en otro caso.
		 * @return OptionDefinition& *this
		 * @return bool True si se permite el prefijo.
		 */
		OptionDefinition&	allowNoPreffix(bool allow = true);
		bool				allowNoPreffix() const;

		/**
		 * Fija y devuelve el valor predeterminado de esta opción.
		 *
		 * @param string defaultValue Valor por defecto.
		 * @return string Valor por defecto.
		 */
		void				defaultValue(const string defaultValue);
		const string		defaultValue() const;

		/**
		 * Elimina el valor predeterminado.
		 */
		void				removeDefaultValue();

		/**
		 * Indica si el valor predeterminado está fijado o no.
		 *
		 * @return bool True si está fijado, false en otro caso.
		 */
		bool				hasDefaultValue() const;

		/**
		 * Fija y devuelve un puntero a la función que hay que ejecutar
		 * cuando se procese esta opción.
		 *
		 * @param OnOptionProcessed executeThis Puntero a la función a
		 * ejecutar.
		 * @return OnOptionProcessed Puntero a la función a ejecutar.
		 */
		void				execute(OnOptionProcessed executeThis);
		OnOptionProcessed	execute() const;

		/**
		 * Fija las cadenas válidas para esta opción.
		 *
		 * @param string validString Cadena válida.
		 * @param StringSet validStrings Cadenas válidas.
		 * @param string[] validStrings Cadenas válidas.
		 * @param int length Longitud del array de cadenas válidas.
		 * @return OptionDefinition& *this
		 * @return StringSet Cadenas válidas.
		 */
		OptionDefinition&	validString(const string validString);
		OptionDefinition&	validStrings(const StringSet validStrings);
		OptionDefinition&	validStrings(const string validStrings[], int length);
		StringSet			validStrings() const;

		/**
		 * Devuelve si esta opción tiene valor mínimo en caso de que su
		 * argumento sea numérico.
		 *
		 * @param float& value Devuelve el valor mínimo en caso de que tenga
		 * valor mínimo.
		 * @return bool True si tiene valor mínimo, false en otro caso.
		 */
		bool				hasMinValue(float& value) const;

		/**
		 * Fija el valor mínimo.
		 *
		 * @param float value Valor mínimo.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	minValue(float value);

		/**
		 * Devuelve si esta opción tiene valor máximo en caso de que su
		 * argumento sea numérico.
		 *
		 * @param float& value Devuelve el valor máximo en caso de que tenga
		 * valor máximo.
		 * @return bool True si tiene valor máximo, false en otro caso.
		 */
		bool				hasMaxValue(float& value) const;

		/**
		 * Fija el valor máximo.
		 *
		 * @param float value Valor máximo.
		 * @return OptionDefinition& *this
		 */
		OptionDefinition&	maxValue(float value);
};

}	// namespace clipp

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


<commit_before>/***************************************************************************
                          autoreplaceplugin.cpp  -  description
                             -------------------
    begin                : 20030425
    copyright            : (C) 2003 by Roberto Pariset
    email                : victorheremita@fastwebnet.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>

#include <qstylesheet.h>
#include <qmap.h>

#include <kdebug.h>
#include <kaction.h>
#include <klocale.h>
#include <kgenericfactory.h>

#include "kopetemessage.h"
#include "kopetemetacontact.h"
#include "kopetemessagemanager.h"
#include "kopetemessagemanagerfactory.h"

#include "autoreplaceplugin.h"
#include "autoreplacepreferences.h"

K_EXPORT_COMPONENT_FACTORY( kopete_autoreplace, KGenericFactory<AutoReplacePlugin> );
AutoReplacePlugin * AutoReplacePlugin::pluginStatic_ = 0L;

AutoReplacePlugin::AutoReplacePlugin(
		QObject *parent, const char * name, const QStringList & )
				: KopetePlugin( parent, name )
{
	if( !pluginStatic_ )
		pluginStatic_ = this;

	m_prefs = new AutoReplacePreferences ( "autoreplace", this );
	map = m_prefs->getMap();	// FIXME make sure it works if map changes (seems to work)

	// autoreplace OUTGOING messages
	connect( KopeteMessageManagerFactory::factory(),
		SIGNAL( aboutToSend( KopeteMessage & ) ),
		SLOT( slotAutoReplaceOutgoingMessage( KopeteMessage & ) ) );

	// autoreplace INCOMING messages
	connect( KopeteMessageManagerFactory::factory(),
		SIGNAL( aboutToDisplay( KopeteMessage & ) ),
		// aboutToDisplay or aboutToReceive ?
		SLOT( slotAutoReplaceIncomingMessage( KopeteMessage & ) ) );

}

AutoReplacePlugin::~AutoReplacePlugin()
{
	pluginStatic_ = 0L;
}

AutoReplacePlugin * AutoReplacePlugin::plugin()
{
	return pluginStatic_ ;
}

void AutoReplacePlugin::slotAutoReplaceOutgoingMessage( KopeteMessage & msg )
{
	if(msg.direction() != KopeteMessage::Outbound)
		return;
	autoReplaceMessage( msg );
}

void AutoReplacePlugin::slotAutoReplaceIncomingMessage( KopeteMessage & msg )
{
	if(msg.direction() != KopeteMessage::Inbound || !m_prefs->getAutoreplaceIncoming())
		return;
	autoReplaceMessage( msg );
}

void AutoReplacePlugin::autoReplaceMessage( KopeteMessage & msg )
{
	QString original_message = msg.plainBody();
	QString replaced_message = original_message;
	AutoReplacePreferences::WordsToReplace map = m_prefs->getMap();

	// replaces all matched words --> try to find a better way
	QString match = "\\b(%1)\\b";
	AutoReplacePreferences::WordsToReplace::Iterator it;
		for ( it = map.begin(); it != map.end(); ++it )
			replaced_message.replace(QRegExp(
					match.arg(QRegExp::escape(it.key()) ) ),
					map.find( it.key() ).data() );

	// eventually add . at the end of the lines, sent lines only
	if( m_prefs->getAddDot() && msg.direction()!=KopeteMessage::Inbound )
		// the next one is used if use no emoticons, for it will add . after
		// lines that end up with emoticons
		// replaced_message.replace(QRegExp( "[^:;,!?]$" ), "\\1." );
		// the next one is used if use emoticons like :d AND :D
		// replaced_message.replace(QRegExp( "([^:;,=!?()@/OoSsPpDd])$" ), "\\1." );
		// the next one is used if use emoticons like :d and NOT :D
		// replaced_message.replace(QRegExp( "([^:;,=!?()@/ospd])$" ), "\\1." );
		// the next one is used if use emoticons like :D and NOT :d
		replaced_message.replace(QRegExp( "([^:;,=!?()@/OSPD])$" ), "\\1." );

	// eventually start each sent line with capital letter
	if( m_prefs->getUpper() && msg.direction()!=KopeteMessage::Inbound )
		replaced_message[0] = replaced_message.at( 0 ).upper();

	// the message is now the one with replaced words
	msg.setBody( replaced_message, KopeteMessage::PlainText );
}

#include "autoreplaceplugin.moc"
<commit_msg>better regexp to check if the dot is needed<commit_after>/***************************************************************************
                          autoreplaceplugin.cpp  -  description
                             -------------------
    begin                : 20030425
    copyright            : (C) 2003 by Roberto Pariset
    email                : victorheremita@fastwebnet.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>

#include <qstylesheet.h>
#include <qmap.h>

#include <kdebug.h>
#include <kaction.h>
#include <klocale.h>
#include <kgenericfactory.h>

#include "kopetemessage.h"
#include "kopetemetacontact.h"
#include "kopetemessagemanager.h"
#include "kopetemessagemanagerfactory.h"

#include "autoreplaceplugin.h"
#include "autoreplacepreferences.h"

K_EXPORT_COMPONENT_FACTORY( kopete_autoreplace, KGenericFactory<AutoReplacePlugin> );
AutoReplacePlugin * AutoReplacePlugin::pluginStatic_ = 0L;

AutoReplacePlugin::AutoReplacePlugin(
		QObject *parent, const char * name, const QStringList & )
				: KopetePlugin( parent, name )
{
	if( !pluginStatic_ )
		pluginStatic_ = this;

	m_prefs = new AutoReplacePreferences ( "autoreplace", this );
	map = m_prefs->getMap();	// FIXME make sure it works if map changes (seems to work)

	// autoreplace OUTGOING messages
	connect( KopeteMessageManagerFactory::factory(),
		SIGNAL( aboutToSend( KopeteMessage & ) ),
		SLOT( slotAutoReplaceOutgoingMessage( KopeteMessage & ) ) );

	// autoreplace INCOMING messages
	connect( KopeteMessageManagerFactory::factory(),
		SIGNAL( aboutToDisplay( KopeteMessage & ) ),
		// aboutToDisplay or aboutToReceive ?
		SLOT( slotAutoReplaceIncomingMessage( KopeteMessage & ) ) );

}

AutoReplacePlugin::~AutoReplacePlugin()
{
	pluginStatic_ = 0L;
}

AutoReplacePlugin * AutoReplacePlugin::plugin()
{
	return pluginStatic_ ;
}

void AutoReplacePlugin::slotAutoReplaceOutgoingMessage( KopeteMessage & msg )
{
	if(msg.direction() != KopeteMessage::Outbound)
		return;
	autoReplaceMessage( msg );
}

void AutoReplacePlugin::slotAutoReplaceIncomingMessage( KopeteMessage & msg )
{
	if(msg.direction() != KopeteMessage::Inbound || !m_prefs->getAutoreplaceIncoming())
		return;
	autoReplaceMessage( msg );
}

void AutoReplacePlugin::autoReplaceMessage( KopeteMessage & msg )
{
	QString original_message = msg.plainBody();
	QString replaced_message = original_message;
	AutoReplacePreferences::WordsToReplace map = m_prefs->getMap();

	// replaces all matched words --> try to find a better way
	QString match = "\\b(%1)\\b";
	AutoReplacePreferences::WordsToReplace::Iterator it;
		for ( it = map.begin(); it != map.end(); ++it )
			replaced_message.replace(QRegExp(
					match.arg(QRegExp::escape(it.key()) ) ),
					map.find( it.key() ).data() );

	// eventually add . at the end of the lines, sent lines only
	if( m_prefs->getAddDot() && msg.direction()!=KopeteMessage::Inbound )
		replaced_message.replace(QRegExp( "([a-z])$" ), "\\1." );
//		replaced_message.replace(QRegExp( "([\\w])$" ), "\\1." );

	// eventually start each sent line with capital letter
	if( m_prefs->getUpper() && msg.direction()!=KopeteMessage::Inbound )
		replaced_message[0] = replaced_message.at( 0 ).upper();

	// the message is now the one with replaced words
	msg.setBody( replaced_message, KopeteMessage::PlainText );
}

#include "autoreplaceplugin.moc"
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** MJPEGVideoSource.cpp
**
** V4L2 RTSP streamer
**
** MJPEG Source for RTSP server
**
** -------------------------------------------------------------------------*/

#include "MJPEGVideoSource.h"

void MJPEGVideoSource::afterGettingFrame(unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
	int headerSize = 0;
	fFrameSize = 0;

	unsigned int i = 0;
	while ( (i<frameSize) && (headerSize==0) ) {
	    // SOF
	    if ( ((i+11) < frameSize)  && (fTo[i] == 0xFF) && (fTo[i+1] == 0xC0) ) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "SOF length:" << length;

		m_height = (fTo[i+5]<<5)|(fTo[i+6]>>3);
		m_width  = (fTo[i+7]<<5)|(fTo[i+8]>>3);

		int hv_subsampling = fTo[i+11];
		if (hv_subsampling == 0x21 ) {
		    m_type = 0; // JPEG 4:2:2
		} else if (hv_subsampling == 0x22 ) {
		    m_type = 1; // JPEG 4:2:0
		} else {
		    LOG(NOTICE) << "not managed sampling:0x" << std::hex << hv_subsampling;
		    m_type = 255;
		}
		LOG(INFO) << "width:" << (int)(m_width<<3) << " height:" << (int)(m_height<<3) << " type:"<< (int)m_type;

		i+=length+2;
	    }
	    // DQT
	    else if ( ( (i+5+64) < frameSize)  && (fTo[i] == 0xFF) && (fTo[i+1] == 0xDB)) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "DQT length:" << length;

		unsigned int precision = fTo[i+4]<<4;
		unsigned int quantIdx  = fTo[i+4]&0x0f;
		unsigned int quantSize = length-3;
		if (quantSize*quantIdx+quantSize <= sizeof(m_qTable)) {
		    memcpy(m_qTable + quantSize*quantIdx, fTo + i + 5, quantSize);
		    if (quantSize*quantIdx+quantSize > m_qTableSize) {
			m_qTableSize = quantSize*quantIdx+quantSize;
			LOG(NOTICE) << "Quantization table idx:" << quantIdx << " precision:" << precision << " size:" << quantSize << " total size:" << m_qTableSize;
		    }
		}

		i+=length+2;
	    }
	    // SOS
	    else if ( ((i+1) < frameSize) && (fTo[i] == 0xFF) && (fTo[i+1] == 0xDA) ) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "SOS length:" << length;

		headerSize = i+length+2;
	    } else {
		i++;
	    }
	}

	if (headerSize != 0) {
	    LOG(DEBUG) << "headerSize:" << headerSize;
	    fFrameSize = frameSize - headerSize;
	    memmove( fTo, fTo + headerSize, fFrameSize );
	} else {
	    LOG(NOTICE) << "Bad header => dropping frame";
	}

	fNumTruncatedBytes = numTruncatedBytes;
	fPresentationTime = presentationTime;
	fDurationInMicroseconds = durationInMicroseconds;
	afterGetting(this);
}

u_int8_t const* MJPEGVideoSource::quantizationTables( u_int8_t& precision, u_int16_t& length )
{
	length = 0;
	precision = 0;
	if (m_qTableSize > 0)
	{
		length = m_qTableSize;
		precision = m_precision;
	}
	return m_qTable;
}
<commit_msg>Update MJPEGVideoSource.cpp<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** MJPEGVideoSource.cpp
**
** V4L2 RTSP streamer
**
** MJPEG Source for RTSP server
**
** -------------------------------------------------------------------------*/

#include "MJPEGVideoSource.h"

void MJPEGVideoSource::afterGettingFrame(unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
	int headerSize = 0;
	fFrameSize = 0;

	unsigned int i = 0;
	while ( (i<frameSize) && (headerSize==0) ) {
	    // SOF
	    if ( ((i+11) < frameSize)  && (fTo[i] == 0xFF) && (fTo[i+1] == 0xC0) ) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "SOF length:" << length;

		m_height = (fTo[i+5]<<5)|(fTo[i+6]>>3);
		m_width  = (fTo[i+7]<<5)|(fTo[i+8]>>3);

		int hv_subsampling = fTo[i+11];
		if (hv_subsampling == 0x21 ) {
		    m_type = 0; // JPEG 4:2:2
		} else if (hv_subsampling == 0x22 ) {
		    m_type = 1; // JPEG 4:2:0
		} else {
		    LOG(NOTICE) << "not managed sampling:0x" << std::hex << hv_subsampling;
		    m_type = 255;
		}
		LOG(INFO) << "width:" << (int)(m_width<<3) << " height:" << (int)(m_height<<3) << " type:"<< (int)m_type;

		i+=length+2;
	    }
	    // DQT
	    else if ( ( (i+5+64) < frameSize)  && (fTo[i] == 0xFF) && (fTo[i+1] == 0xDB)) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "DQT length:" << length;

		unsigned int precision = (fTo[i+4]&0xf0)<<4;
		unsigned int quantIdx  = fTo[i+4]&0x0f;
		unsigned int quantSize = length-3;
		if (quantSize*quantIdx+quantSize <= sizeof(m_qTable)) {
		    memcpy(m_qTable + quantSize*quantIdx, fTo + i + 5, quantSize);
		    LOG(NOTICE) << "Quantization table idx:" << quantIdx << " precision:" << precision << " size:" << quantSize << " total size:" << m_qTableSize;
		    if (quantSize*quantIdx+quantSize > m_qTableSize) {
			m_qTableSize = quantSize*quantIdx+quantSize;
		    }
		}

		i+=length+2;
	    }
	    // SOS
	    else if ( ((i+1) < frameSize) && (fTo[i] == 0xFF) && (fTo[i+1] == 0xDA) ) {
		int length = (fTo[i+2]<<8)|(fTo[i+3]);
		LOG(DEBUG) << "SOS length:" << length;

		headerSize = i+length+2;
	    } else {
		i++;
	    }
	}

	if (headerSize != 0) {
	    LOG(DEBUG) << "headerSize:" << headerSize;
	    fFrameSize = frameSize - headerSize;
	    memmove( fTo, fTo + headerSize, fFrameSize );
	} else {
	    LOG(NOTICE) << "Bad header => dropping frame";
	}

	fNumTruncatedBytes = numTruncatedBytes;
	fPresentationTime = presentationTime;
	fDurationInMicroseconds = durationInMicroseconds;
	afterGetting(this);
}

u_int8_t const* MJPEGVideoSource::quantizationTables( u_int8_t& precision, u_int16_t& length )
{
	length = 0;
	precision = 0;
	if (m_qTableSize > 0)
	{
		length = m_qTableSize;
		precision = m_precision;
	}
	return m_qTable;
}
<|endoftext|>


<commit_before>#ifndef GCN_ACTIONLISTENER_HPP
#define GCN_ACTIONLISTENER_HPP

#include <string>

namespace gcn
{
  /**
   *
   */
  class ActionListener
  {
  public:
    /**
     *
     */
    virtual ~ActionListener();

    /**
     *
     */
    virtual void actionEvent(const std::string& eventId) = 0;

  }; // end ActionListener

} // end gcn

#endif // end GCN_ACTIONLISTENER_HPP
<commit_msg>Added comments, renamed actionEvent to action<commit_after>#ifndef GCN_ACTIONLISTENER_HPP
#define GCN_ACTIONLISTENER_HPP

#include <string>

namespace gcn
{
  /**
   * A ActionListener listens for action events from a widget.
   *
   * @see Widget::addActionListener
   */
  class ActionListener
  {
  public:

    /**
     * Destructor.
     */
    virtual ~ActionListener() { }

    /**
     * This function is called upon an action recieved from a widget.
     *
     * @param eventId the identifier of the widget.
     */
    virtual void action(const std::string& eventId) = 0;

  }; // end ActionListener

} // end gcn

#endif // end GCN_ACTIONLISTENER_HPP
<|endoftext|>


<commit_before>//
//  Iir.cpp
//  MUSI8903
//
//  Created by Siyuan Niu on 1/27/16.
//
//

#include <stdio.h>
#include <iostream>
#include <cmath>

#include "Iir.h"

//constructor
IirComb::IirComb() {}

IirComb::~IirComb() {}

Error_t IirComb::filtering(float **inputBuffer, float **outputBuffer, int numSamples) {
    //for each channel
    for (int channel = 0; channel < filterNumChannels; channel++) {

        //for each frame
        for (int dataFrame = 0; dataFrame < numSamples; dataFrame++) {

            //feedbackward
            outputBuffer[channel][dataFrame] = inputBuffer[channel][dataFrame] + gain*delayBuffer[channel][delayLineInSamples-1];

            //iterate the delayline
            for (int i = delayLineInSamples-1; i > 0 ; i--) {
                delayBuffer[channel][i] = delayBuffer[channel][i-1];
            }

            delayBuffer[channel][0] = outputBuffer[channel][dataFrame];

        }
    }

    return kNoError;
}

void IirComb::setDelayLineInSamples(long int leng)
{
    delayLineInSamples = leng;
}

void IirComb::setGain(float g) {
    if (fabs(g) > 1)
    {
        std::cout << "Incorrect parameter value for filter gain. Magnitude should be <= 1" << std::endl;
        exit(0);
    }
    gain = g;
}

<commit_msg>comment<commit_after>//
//  Iir.cpp
//  MUSI8903
//
//  Created by Siyuan Niu on 1/27/16.
//
//

#include <stdio.h>
#include <iostream>
#include <cmath>

#include "Iir.h"

//constructor
IirComb::IirComb() {}

IirComb::~IirComb() {}

Error_t IirComb::filtering(float **inputBuffer, float **outputBuffer, int numSamples) {
    //for each channel
    for (int channel = 0; channel < filterNumChannels; channel++) {

        //for each frame
        for (int dataFrame = 0; dataFrame < numSamples; dataFrame++) {

            //feedbackward
            outputBuffer[channel][dataFrame] = inputBuffer[channel][dataFrame] + gain*delayBuffer[channel][delayLineInSamples-1];

            //iterate the delayline
            for (int i = delayLineInSamples-1; i > 0 ; i--) {
                delayBuffer[channel][i] = delayBuffer[channel][i-1];
            }

            delayBuffer[channel][0] = outputBuffer[channel][dataFrame];

        }
    }

    return kNoError;
}

//set the length of the delay line
void IirComb::setDelayLineInSamples(long int leng)
{
    delayLineInSamples = leng;
}

//set the gain
void IirComb::setGain(float g) {
    if (fabs(g) > 1)
    {
        std::cout << "Incorrect parameter value for filter gain. Magnitude should be <= 1" << std::endl;
        exit(0);
    }
    gain = g;
}

<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_BASICCONTAINER_HPP
#define GCN_BASICCONTAINER_HPP

#include <list>

#include "guichan/platform.hpp"
#include "guichan/graphics.hpp"
#include "guichan/widget.hpp"

namespace gcn
{
    /**
     * Containers base class. Includes basic container functions
     * every container should have. Ccontainers should
     * inherit from this class and implement it's functions.
     *
     * @see Container
     */
    class GCN_CORE_DECLSPEC BasicContainer: public Widget
    {
    public:

        virtual ~BasicContainer() { }

        /**
         * Moves a Widget to the top of the BasicContainer.
         * The widget will be drawn above all other Widgets in the
         * BasicContainer.
         *
         * @param widget the Widget to move.
         */
        virtual void moveToTop(Widget* widget) = 0;

        /**
         * Moves a widget to the bottom of the BasicContainer.
         * The Widget will be drawn below all other Widgets in the
         * BasicContainer.
         *
         * @param widget the Widget to move.
         */
        virtual void moveToBottom(Widget* widget) = 0;

        /**
         * Gets the drawing space size a Widget has in the BasicContainer.
         * It may not be the same size as the Widgets width and height.
         *
         * NOTE: Size is not checked recursively all the way back to the
         *       top Widget. If the BasicContainer itself is clipped,
         *       the size may be inaccurate.
         *
         * @param width the width the Widget's draw space has.
         * @param height the height the Widget's draw space has.
         * @param widget the Widget calling the function.
         */
        virtual void getDrawSize(int& width, int& height, Widget* widget) = 0;

        /**
         * Called when a child of the BasicContainer gets destroyed.
         *
         * @param widget the destroyed Widget.
         */
        virtual void _announceDeath(Widget *widget) = 0;

    };
}

#endif // end GCN_BASICCONTAINER_HPP
<commit_msg>Fixed comment typo.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_BASICCONTAINER_HPP
#define GCN_BASICCONTAINER_HPP

#include <list>

#include "guichan/platform.hpp"
#include "guichan/graphics.hpp"
#include "guichan/widget.hpp"

namespace gcn
{
    /**
     * Containers base class. Includes basic container functions
     * every container should have. Containers should
     * inherit from this class and implement it's functions.
     *
     * @see Container
     */
    class GCN_CORE_DECLSPEC BasicContainer: public Widget
    {
    public:

        virtual ~BasicContainer() { }

        /**
         * Moves a Widget to the top of the BasicContainer.
         * The widget will be drawn above all other Widgets in the
         * BasicContainer.
         *
         * @param widget the Widget to move.
         */
        virtual void moveToTop(Widget* widget) = 0;

        /**
         * Moves a widget to the bottom of the BasicContainer.
         * The Widget will be drawn below all other Widgets in the
         * BasicContainer.
         *
         * @param widget the Widget to move.
         */
        virtual void moveToBottom(Widget* widget) = 0;

        /**
         * Gets the drawing space size a Widget has in the BasicContainer.
         * It may not be the same size as the Widgets width and height.
         *
         * NOTE: Size is not checked recursively all the way back to the
         *       top Widget. If the BasicContainer itself is clipped,
         *       the size may be inaccurate.
         *
         * @param width the width the Widget's draw space has.
         * @param height the height the Widget's draw space has.
         * @param widget the Widget calling the function.
         */
        virtual void getDrawSize(int& width, int& height, Widget* widget) = 0;

        /**
         * Called when a child of the BasicContainer gets destroyed.
         *
         * @param widget the destroyed Widget.
         */
        virtual void _announceDeath(Widget *widget) = 0;

    };
}

#endif // end GCN_BASICCONTAINER_HPP
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"

// This is a GR test
#if SK_SUPPORT_GPU
#include "..\src\gpu\GrTHashCache.h"

struct HashElement {
    int     fKey;
    int     fValue;
};

class GrFindPositivesFunctor {
public:
    // only return elements with positive values
    bool operator()(const HashElement* elem) const {
        return elem->fValue > 0;
    }
};

class GrFindNegativesFunctor {
public:
    // only return elements with negative values
    bool operator()(const HashElement* elem) const {
        return elem->fValue < 0;
    }
};

class HashKey {
public:
    HashKey(int key) : fKey(key) {}

    uint32_t getHash() const { return fKey; }

    static bool LT(const HashElement& entry, const HashKey& key) {
        return entry.fKey < key.fKey;
    }
    static bool EQ(const HashElement& entry, const HashKey& key) {
        return entry.fKey == key.fKey;
    }

#if GR_DEBUG
    static uint32_t GetHash(const HashElement& entry) {
        return entry.fKey;
    }
    static bool LT(const HashElement& a, const HashElement& b) {
        return a.fKey < b.fKey;
    }
    static bool EQ(const HashElement& a, const HashElement& b) {
        return a.fKey == b.fKey;
    }
#endif

protected:
    int fKey;
};

////////////////////////////////////////////////////////////////////////////////
static void TestHashCache(skiatest::Reporter* reporter, GrContext* context) {

    GrTHashTable<HashElement, HashKey, 4> cache;

    HashElement negHashElements[10] = {
        { 0,  0 },
        { 1, -1 },
        { 2, -2 },
        { 3, -3 },
        { 4, -4 },
        { 5, -5 },
        { 6, -6 },
        { 7, -7 },
        { 8, -8 },
        { 9, -9 }
    };
    HashElement posHashElements[10] = {
        { 0, 0 },
        { 1, 1 },
        { 2, 2 },
        { 3, 3 },
        { 4, 4 },
        { 5, 5 },
        { 6, 6 },
        { 7, 7 },
        { 8, 8 },
        { 9, 9 }
    };

    // add i: -i pairs
    for (int i = 0; i < 10; ++i) {
        cache.insert(HashKey(i), &negHashElements[i]);
    }

    REPORTER_ASSERT(reporter, 10 == cache.count());

    // look for all i's and assert we found the -i's
    for (int i = 0; i < 10; ++i) {
        HashElement* found = cache.find(i);
        REPORTER_ASSERT(reporter, NULL != found && -i == found->fValue);
    }

    // look for something not in the cache
    {
        HashElement* found = cache.find(10);
        REPORTER_ASSERT(reporter, NULL == found);
    }

    // add i:i duplicates (so each i will have a positive & negative entry)
    for (int i = 0; i < 10; ++i) {
        cache.insert(i, &posHashElements[i]);
    }

    REPORTER_ASSERT(reporter, 20 == cache.count());

    // test out the find functor to find all the positive values
    {
        GrFindPositivesFunctor findPos;

        HashElement* found = cache.find(0, findPos);
        REPORTER_ASSERT(reporter, NULL == found);

        for (int i = 1; i < 10; ++i) {
            found = cache.find(i, findPos);

            REPORTER_ASSERT(reporter, NULL != found && found->fValue > 0);
        }
    }

    // make sure finding the positives wasn't a fluke - find the negatives
    {
        GrFindNegativesFunctor findNeg;

        HashElement* found = cache.find(0, findNeg);
        REPORTER_ASSERT(reporter, NULL == found);

        for (int i = 1; i < 10; ++i) {
            found = cache.find(i, findNeg);

            REPORTER_ASSERT(reporter, NULL != found && found->fValue < 0);
        }
    }

    // remove the 0:0 entries
    {
        cache.remove(0, &negHashElements[0]);
        cache.remove(0, &posHashElements[0]);
        REPORTER_ASSERT(reporter, 18 == cache.count());

        HashElement* found = cache.find(0);
        REPORTER_ASSERT(reporter, NULL == found);
    }

    // remove all
    {
        cache.removeAll();
        REPORTER_ASSERT(reporter, 0 == cache.count());
    }
}

////////////////////////////////////////////////////////////////////////////////
#include "TestClassDef.h"
DEFINE_GPUTESTCLASS("HashCache", HashCacheTestClass, TestHashCache)

#endif
<commit_msg>Fix for r5587 compiler error (removed ../src/gpu in HashCacheTest.cpp)<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"

// This is a GR test
#if SK_SUPPORT_GPU
#include "GrTHashCache.h"

struct HashElement {
    int     fKey;
    int     fValue;
};

class GrFindPositivesFunctor {
public:
    // only return elements with positive values
    bool operator()(const HashElement* elem) const {
        return elem->fValue > 0;
    }
};

class GrFindNegativesFunctor {
public:
    // only return elements with negative values
    bool operator()(const HashElement* elem) const {
        return elem->fValue < 0;
    }
};

class HashKey {
public:
    HashKey(int key) : fKey(key) {}

    uint32_t getHash() const { return fKey; }

    static bool LT(const HashElement& entry, const HashKey& key) {
        return entry.fKey < key.fKey;
    }
    static bool EQ(const HashElement& entry, const HashKey& key) {
        return entry.fKey == key.fKey;
    }

#if GR_DEBUG
    static uint32_t GetHash(const HashElement& entry) {
        return entry.fKey;
    }
    static bool LT(const HashElement& a, const HashElement& b) {
        return a.fKey < b.fKey;
    }
    static bool EQ(const HashElement& a, const HashElement& b) {
        return a.fKey == b.fKey;
    }
#endif

protected:
    int fKey;
};

////////////////////////////////////////////////////////////////////////////////
static void TestHashCache(skiatest::Reporter* reporter, GrContext* context) {

    GrTHashTable<HashElement, HashKey, 4> cache;

    HashElement negHashElements[10] = {
        { 0,  0 },
        { 1, -1 },
        { 2, -2 },
        { 3, -3 },
        { 4, -4 },
        { 5, -5 },
        { 6, -6 },
        { 7, -7 },
        { 8, -8 },
        { 9, -9 }
    };
    HashElement posHashElements[10] = {
        { 0, 0 },
        { 1, 1 },
        { 2, 2 },
        { 3, 3 },
        { 4, 4 },
        { 5, 5 },
        { 6, 6 },
        { 7, 7 },
        { 8, 8 },
        { 9, 9 }
    };

    // add i: -i pairs
    for (int i = 0; i < 10; ++i) {
        cache.insert(HashKey(i), &negHashElements[i]);
    }

    REPORTER_ASSERT(reporter, 10 == cache.count());

    // look for all i's and assert we found the -i's
    for (int i = 0; i < 10; ++i) {
        HashElement* found = cache.find(i);
        REPORTER_ASSERT(reporter, NULL != found && -i == found->fValue);
    }

    // look for something not in the cache
    {
        HashElement* found = cache.find(10);
        REPORTER_ASSERT(reporter, NULL == found);
    }

    // add i:i duplicates (so each i will have a positive & negative entry)
    for (int i = 0; i < 10; ++i) {
        cache.insert(i, &posHashElements[i]);
    }

    REPORTER_ASSERT(reporter, 20 == cache.count());

    // test out the find functor to find all the positive values
    {
        GrFindPositivesFunctor findPos;

        HashElement* found = cache.find(0, findPos);
        REPORTER_ASSERT(reporter, NULL == found);

        for (int i = 1; i < 10; ++i) {
            found = cache.find(i, findPos);

            REPORTER_ASSERT(reporter, NULL != found && found->fValue > 0);
        }
    }

    // make sure finding the positives wasn't a fluke - find the negatives
    {
        GrFindNegativesFunctor findNeg;

        HashElement* found = cache.find(0, findNeg);
        REPORTER_ASSERT(reporter, NULL == found);

        for (int i = 1; i < 10; ++i) {
            found = cache.find(i, findNeg);

            REPORTER_ASSERT(reporter, NULL != found && found->fValue < 0);
        }
    }

    // remove the 0:0 entries
    {
        cache.remove(0, &negHashElements[0]);
        cache.remove(0, &posHashElements[0]);
        REPORTER_ASSERT(reporter, 18 == cache.count());

        HashElement* found = cache.find(0);
        REPORTER_ASSERT(reporter, NULL == found);
    }

    // remove all
    {
        cache.removeAll();
        REPORTER_ASSERT(reporter, 0 == cache.count());
    }
}

////////////////////////////////////////////////////////////////////////////////
#include "TestClassDef.h"
DEFINE_GPUTESTCLASS("HashCache", HashCacheTestClass, TestHashCache)

#endif
<|endoftext|>


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

//$Id$

#ifndef FEATURE_FACTORY_HPP
#define FEATURE_FACTORY_HPP

#include <mapnik/feature.hpp>

namespace mapnik
{
struct feature_factory
{
    static Feature* create (int fid)
    {
        return new Feature(fid);
    }
};
}

#endif //FEATURE_FACTORY_HPP
<commit_msg>+ use boost::make_shared to improve shared_ptr   allocation locality<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_FACTORY_HPP
#define FEATURE_FACTORY_HPP

#include <mapnik/feature.hpp>
#include <boost/make_shared.hpp>
//#include <boost/pool/pool_alloc.hpp>

namespace mapnik
{
struct feature_factory
{
    static boost::shared_ptr<Feature> create (int fid)
    {
        //return boost::allocate_shared<Feature>(boost::pool_allocator<Feature>(),fid);
        //return boost::allocate_shared<Feature>(boost::fast_pool_allocator<Feature>(),fid);
        return boost::make_shared<Feature>(fid);
    }

};
}

#endif //FEATURE_FACTORY_HPP
<|endoftext|>