<commit_before>#include "sass.hpp"
#include "ast.hpp"
#include "output.hpp"

namespace Sass {

  Output::Output(Sass_Output_Options& opt)
  : Inspect(Emitter(opt)),
    charset(""),
    top_nodes(0)
  {}

  Output::~Output() { }

  void Output::fallback_impl(AST_Node* n)
  {
    return n->perform(this);
  }

  void Output::operator()(Number* n)
  {
    // use values to_string facility
    std::string res = n->to_string(opt);
    // check for a valid unit here
    // includes result for reporting
    if (!n->is_valid_css_unit()) {
      throw Exception::InvalidValue(*n);
    }
    // output the final token
    append_token(res, n);
  }

  void Output::operator()(Import* imp)
  {
    top_nodes.push_back(imp);
  }

  void Output::operator()(Map* m)
  {
    std::string dbg(m->to_string(opt));
    error(dbg + " isn't a valid CSS value.", m->pstate());
  }

  OutputBuffer Output::get_buffer(void)
  {

    Emitter emitter(opt);
    Inspect inspect(emitter);

    size_t size_nodes = top_nodes.size();
    for (size_t i = 0; i < size_nodes; i++) {
      top_nodes[i]->perform(&inspect);
      inspect.append_mandatory_linefeed();
    }

    // flush scheduled outputs
    // maybe omit semicolon if possible
    inspect.finalize(wbuf.buffer.size() == 0);
    // prepend buffer on top
    prepend_output(inspect.output());
    // make sure we end with a linefeed
    if (!ends_with(wbuf.buffer, opt.linefeed)) {
      // if the output is not completely empty
      if (!wbuf.buffer.empty()) append_string(opt.linefeed);
    }

    // search for unicode char
    for(const char& chr : wbuf.buffer) {
      // skip all ascii chars
      if (chr >= 0) continue;
      // declare the charset
      if (output_style() != COMPRESSED)
        charset = "@charset \"UTF-8\";"
                + std::string(opt.linefeed);
      else charset = "\xEF\xBB\xBF";
      // abort search
      break;
    }

    // add charset as first line, before comments and imports
    if (!charset.empty()) prepend_string(charset);

    return wbuf;

  }

  void Output::operator()(Comment* c)
  {
    std::string txt = c->text()->to_string(opt);
    // if (indentation && txt == "/**/") return;
    bool important = c->is_important();
    if (output_style() != COMPRESSED || important) {
      if (buffer().size() == 0) {
        top_nodes.push_back(c);
      } else {
        in_comment = true;
        append_indentation();
        c->text()->perform(this);
        in_comment = false;
        if (indentation == 0) {
          append_mandatory_linefeed();
        } else {
          append_optional_linefeed();
        }
      }
    }
  }

  void Output::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();
    bool      decls = false;

    // Filter out rulesets that aren't printable (process its children though)
    if (!Util::isPrintable(r, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (b->has_non_hoistable()) {
      decls = true;
      if (output_style() == NESTED) indentation += r->tabs();
      if (opt.source_comments) {
        std::stringstream ss;
        append_indentation();
        ss << "/* line " << r->pstate().line + 1 << ", " << r->pstate().path << " */";
        append_string(ss.str());
        append_optional_linefeed();
      }
      s->perform(this);
      append_scope_opener(b);
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        bool bPrintExpression = true;
        // Check print conditions
        if (typeid(*stm) == typeid(Declaration)) {
          Declaration* dec = static_cast<Declaration*>(stm);
          if (dec->value()->concrete_type() == Expression::STRING) {
            String_Constant* valConst = static_cast<String_Constant*>(dec->value());
            std::string val(valConst->value());
            if (auto qstr = dynamic_cast<String_Quoted*>(valConst)) {
              if (!qstr->quote_mark() && val.empty()) {
                bPrintExpression = false;
              }
            }
          }
          else if (dec->value()->concrete_type() == Expression::LIST) {
            List* list = static_cast<List*>(dec->value());
            bool all_invisible = true;
            for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
              Expression* item = (*list)[list_i];
              if (!item->is_invisible()) all_invisible = false;
            }
            if (all_invisible) bPrintExpression = false;
          }
        }
        // Print if OK
        if (!stm->is_hoistable() && bPrintExpression) {
          stm->perform(this);
        }
      }
      if (output_style() == NESTED) indentation -= r->tabs();
      append_scope_closer(b);
    }

    if (b->has_hoistable()) {
      if (decls) ++indentation;
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
      if (decls) --indentation;
    }
  }

  void Output::operator()(Keyframe_Rule* r)
  {
    Block* b = r->block();
    Selector* v = r->selector();

    if (v) {
      v->perform(this);
    }

    if (!b) {
      append_colon_separator();
      return;
    }

    append_scope_opener();
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1) append_special_linefeed();
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    append_scope_closer();
  }

  void Output::operator()(Supports_Block* f)
  {
    if (f->is_invisible()) return;

    Supports_Condition* c = f->condition();
    Block* b              = f->block();

    // Filter out feature blocks that aren't printable (process its children though)
    if (!Util::isPrintable(f, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (output_style() == NESTED) indentation += f->tabs();
    append_indentation();
    append_token("@supports", f);
    append_mandatory_space();
    c->perform(this);
    append_scope_opener();

    if (b->has_non_hoistable()) {
      // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
      append_scope_opener();

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }

      append_scope_closer();

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
    else {
      // JMA - not hoisted, just output in order
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        stm->perform(this);
        if (i < L - 1) append_special_linefeed();
      }
    }

    if (output_style() == NESTED) indentation -= f->tabs();

    append_scope_closer();

  }

  void Output::operator()(Media_Block* m)
  {
    if (m->is_invisible()) return;

    List*  q     = m->media_queries();
    Block* b     = m->block();

    // Filter out media blocks that aren't printable (process its children though)
    if (!Util::isPrintable(m, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }
    if (output_style() == NESTED) indentation += m->tabs();
    append_indentation();
    append_token("@media", m);
    append_mandatory_space();
    in_media_block = true;
    q->perform(this);
    in_media_block = false;
    append_scope_opener();

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      if ((*b)[i]) (*b)[i]->perform(this);
      if (i < L - 1) append_special_linefeed();
    }

    if (output_style() == NESTED) indentation -= m->tabs();
    append_scope_closer();
  }

  void Output::operator()(At_Rule* a)
  {
    std::string      kwd   = a->keyword();
    Selector*   s     = a->selector();
    Expression* v     = a->value();
    Block*      b     = a->block();

    append_indentation();
    append_token(kwd, a);
    if (s) {
      append_mandatory_space();
      in_wrapped = true;
      s->perform(this);
      in_wrapped = false;
    }
    if (v) {
      append_mandatory_space();
      // ruby sass bug? should use options?
      append_token(v->to_string(/* opt */), v);
    }
    if (!b) {
      append_delimiter();
      return;
    }

    if (b->is_invisible() || b->length() == 0) {
      append_optional_space();
      return append_string("{}");
    }

    append_scope_opener();

    bool format = kwd != "@font-face";;

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1 && format) append_special_linefeed();
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1 && format) append_special_linefeed();
      }
    }

    append_scope_closer();
  }

  void Output::operator()(String_Quoted* s)
  {
    if (s->quote_mark()) {
      append_token(quote(s->value(), s->quote_mark()), s);
    } else if (!in_comment) {
      append_token(string_to_output(s->value()), s);
    } else {
      append_token(s->value(), s);
    }
  }

  void Output::operator()(String_Constant* s)
  {
    std::string value(s->value());
    if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
      value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
    }
    if (!in_comment) {
      append_token(string_to_output(value), s);
    } else {
      append_token(value, s);
    }
  }

}
<commit_msg>Handle signed char when considering @charset<commit_after>#include "sass.hpp"
#include "ast.hpp"
#include "output.hpp"

namespace Sass {

  Output::Output(Sass_Output_Options& opt)
  : Inspect(Emitter(opt)),
    charset(""),
    top_nodes(0)
  {}

  Output::~Output() { }

  void Output::fallback_impl(AST_Node* n)
  {
    return n->perform(this);
  }

  void Output::operator()(Number* n)
  {
    // use values to_string facility
    std::string res = n->to_string(opt);
    // check for a valid unit here
    // includes result for reporting
    if (!n->is_valid_css_unit()) {
      throw Exception::InvalidValue(*n);
    }
    // output the final token
    append_token(res, n);
  }

  void Output::operator()(Import* imp)
  {
    top_nodes.push_back(imp);
  }

  void Output::operator()(Map* m)
  {
    std::string dbg(m->to_string(opt));
    error(dbg + " isn't a valid CSS value.", m->pstate());
  }

  OutputBuffer Output::get_buffer(void)
  {

    Emitter emitter(opt);
    Inspect inspect(emitter);

    size_t size_nodes = top_nodes.size();
    for (size_t i = 0; i < size_nodes; i++) {
      top_nodes[i]->perform(&inspect);
      inspect.append_mandatory_linefeed();
    }

    // flush scheduled outputs
    // maybe omit semicolon if possible
    inspect.finalize(wbuf.buffer.size() == 0);
    // prepend buffer on top
    prepend_output(inspect.output());
    // make sure we end with a linefeed
    if (!ends_with(wbuf.buffer, opt.linefeed)) {
      // if the output is not completely empty
      if (!wbuf.buffer.empty()) append_string(opt.linefeed);
    }

    // search for unicode char
    for(const char& chr : wbuf.buffer) {
      // skip all ascii chars
      // static cast to unsigned to handle `char` being signed / unsigned
      if (static_cast<unsigned>(chr) < 128) continue;
      // declare the charset
      if (output_style() != COMPRESSED)
        charset = "@charset \"UTF-8\";"
                + std::string(opt.linefeed);
      else charset = "\xEF\xBB\xBF";
      // abort search
      break;
    }

    // add charset as first line, before comments and imports
    if (!charset.empty()) prepend_string(charset);

    return wbuf;

  }

  void Output::operator()(Comment* c)
  {
    std::string txt = c->text()->to_string(opt);
    // if (indentation && txt == "/**/") return;
    bool important = c->is_important();
    if (output_style() != COMPRESSED || important) {
      if (buffer().size() == 0) {
        top_nodes.push_back(c);
      } else {
        in_comment = true;
        append_indentation();
        c->text()->perform(this);
        in_comment = false;
        if (indentation == 0) {
          append_mandatory_linefeed();
        } else {
          append_optional_linefeed();
        }
      }
    }
  }

  void Output::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();
    bool      decls = false;

    // Filter out rulesets that aren't printable (process its children though)
    if (!Util::isPrintable(r, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (b->has_non_hoistable()) {
      decls = true;
      if (output_style() == NESTED) indentation += r->tabs();
      if (opt.source_comments) {
        std::stringstream ss;
        append_indentation();
        ss << "/* line " << r->pstate().line + 1 << ", " << r->pstate().path << " */";
        append_string(ss.str());
        append_optional_linefeed();
      }
      s->perform(this);
      append_scope_opener(b);
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        bool bPrintExpression = true;
        // Check print conditions
        if (typeid(*stm) == typeid(Declaration)) {
          Declaration* dec = static_cast<Declaration*>(stm);
          if (dec->value()->concrete_type() == Expression::STRING) {
            String_Constant* valConst = static_cast<String_Constant*>(dec->value());
            std::string val(valConst->value());
            if (auto qstr = dynamic_cast<String_Quoted*>(valConst)) {
              if (!qstr->quote_mark() && val.empty()) {
                bPrintExpression = false;
              }
            }
          }
          else if (dec->value()->concrete_type() == Expression::LIST) {
            List* list = static_cast<List*>(dec->value());
            bool all_invisible = true;
            for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
              Expression* item = (*list)[list_i];
              if (!item->is_invisible()) all_invisible = false;
            }
            if (all_invisible) bPrintExpression = false;
          }
        }
        // Print if OK
        if (!stm->is_hoistable() && bPrintExpression) {
          stm->perform(this);
        }
      }
      if (output_style() == NESTED) indentation -= r->tabs();
      append_scope_closer(b);
    }

    if (b->has_hoistable()) {
      if (decls) ++indentation;
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
      if (decls) --indentation;
    }
  }

  void Output::operator()(Keyframe_Rule* r)
  {
    Block* b = r->block();
    Selector* v = r->selector();

    if (v) {
      v->perform(this);
    }

    if (!b) {
      append_colon_separator();
      return;
    }

    append_scope_opener();
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1) append_special_linefeed();
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    append_scope_closer();
  }

  void Output::operator()(Supports_Block* f)
  {
    if (f->is_invisible()) return;

    Supports_Condition* c = f->condition();
    Block* b              = f->block();

    // Filter out feature blocks that aren't printable (process its children though)
    if (!Util::isPrintable(f, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (output_style() == NESTED) indentation += f->tabs();
    append_indentation();
    append_token("@supports", f);
    append_mandatory_space();
    c->perform(this);
    append_scope_opener();

    if (b->has_non_hoistable()) {
      // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
      append_scope_opener();

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }

      append_scope_closer();

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
    else {
      // JMA - not hoisted, just output in order
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        stm->perform(this);
        if (i < L - 1) append_special_linefeed();
      }
    }

    if (output_style() == NESTED) indentation -= f->tabs();

    append_scope_closer();

  }

  void Output::operator()(Media_Block* m)
  {
    if (m->is_invisible()) return;

    List*  q     = m->media_queries();
    Block* b     = m->block();

    // Filter out media blocks that aren't printable (process its children though)
    if (!Util::isPrintable(m, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }
    if (output_style() == NESTED) indentation += m->tabs();
    append_indentation();
    append_token("@media", m);
    append_mandatory_space();
    in_media_block = true;
    q->perform(this);
    in_media_block = false;
    append_scope_opener();

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      if ((*b)[i]) (*b)[i]->perform(this);
      if (i < L - 1) append_special_linefeed();
    }

    if (output_style() == NESTED) indentation -= m->tabs();
    append_scope_closer();
  }

  void Output::operator()(At_Rule* a)
  {
    std::string      kwd   = a->keyword();
    Selector*   s     = a->selector();
    Expression* v     = a->value();
    Block*      b     = a->block();

    append_indentation();
    append_token(kwd, a);
    if (s) {
      append_mandatory_space();
      in_wrapped = true;
      s->perform(this);
      in_wrapped = false;
    }
    if (v) {
      append_mandatory_space();
      // ruby sass bug? should use options?
      append_token(v->to_string(/* opt */), v);
    }
    if (!b) {
      append_delimiter();
      return;
    }

    if (b->is_invisible() || b->length() == 0) {
      append_optional_space();
      return append_string("{}");
    }

    append_scope_opener();

    bool format = kwd != "@font-face";;

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1 && format) append_special_linefeed();
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
        if (i < L - 1 && format) append_special_linefeed();
      }
    }

    append_scope_closer();
  }

  void Output::operator()(String_Quoted* s)
  {
    if (s->quote_mark()) {
      append_token(quote(s->value(), s->quote_mark()), s);
    } else if (!in_comment) {
      append_token(string_to_output(s->value()), s);
    } else {
      append_token(s->value(), s);
    }
  }

  void Output::operator()(String_Constant* s)
  {
    std::string value(s->value());
    if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
      value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
    }
    if (!in_comment) {
      append_token(string_to_output(value), s);
    } else {
      append_token(value, s);
    }
  }

}
<|endoftext|>


<commit_before>#ifndef SILICIUM_LINUX_OPEN_HPP
#define SILICIUM_LINUX_OPEN_HPP

#include <silicium/error_or.hpp>
#include <silicium/file_descriptor.hpp>
#include <boost/filesystem/path.hpp>

#ifdef __linux__
#	include <fcntl.h>
#endif

namespace Si
{
	inline error_or<file_descriptor> open_reading(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDONLY);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> create_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> overwrite_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_WRONLY | O_EXCL | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> open_read_write(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}
}

#endif
<commit_msg>correct the open flags in overwrite_file<commit_after>#ifndef SILICIUM_LINUX_OPEN_HPP
#define SILICIUM_LINUX_OPEN_HPP

#include <silicium/error_or.hpp>
#include <silicium/file_descriptor.hpp>
#include <boost/filesystem/path.hpp>

#ifdef __linux__
#	include <fcntl.h>
#endif

namespace Si
{
	inline error_or<file_descriptor> open_reading(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDONLY);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> create_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> overwrite_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> open_read_write(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}
}

#endif
<|endoftext|>


<commit_before>#include "Bussi.h"
#include "Polymer.h"
#include "Monomer.h"
#include "Thermostat.h"
#include "Rand.h"
#include <string>

const std::string Bussi::m_name = "Bussi";

Bussi::Bussi(Polymer &polymere, double timestep, double coupling_time)
	: Thermostat(polymere, timestep)
	, couplingtime(coupling_time)
{
	couplingtimeNfInverse = 1.0 / (couplingtime * m_poly.monomers.size());
	m_dtime_half = m_dtime * 0.5;
	cout << "CouplingInv" << couplingtimeNfInverse << endl << "Size" << m_poly.monomers.size();
}

void Bussi::propagate()
{
	//1. velocity verlet:
	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime_half * m.force / m_poly.monomer_mass;
		m.position += m_dtime * m.velocity;
	}
	m_poly.update_forces();
	for (auto& m : m_poly.monomers) m.velocity += m_dtime_half * m.force / m_poly.monomer_mass;

	//2. calculate target kinetic energy (as in the paper from bussi&donadio&parrinello)
	double ekin = m_poly.update_ekin();
	double wienernoise = Rand::real_normal(); // dW in the paper - N(0,1)
	double berendsen = (m_poly.target_temperature() - ekin)*m_dtime / couplingtime;
	double stochastic = 2.0* sqrt((ekin * m_poly.target_temperature()) * couplingtimeNfInverse) * wienernoise;
	double stoch_ekin = ekin + berendsen + stochastic; // evolve ekin with. stochastic dgl  (K_1 = K_0 + dK)

	//3. calculate scaling factor (as with gaussian thermostat)
	double scalingfactor = sqrt(stoch_ekin / ekin);
	//4. rescale
	for (auto& m : m_poly.monomers) m.velocity *= scalingfactor;
}

void Bussi::update_temp() {
}

std::string Bussi::name() const { return m_name; }

std::string Bussi::info() const {
	std::string str{ "Thermostat " };
	str += m_name;
	str += " dtime ";
	str += std::to_string(m_dtime);
	str += " couplTime ";
	str += std::to_string(couplingtime);
	return str;
}
<commit_msg>fixed nan error<commit_after>#include "Bussi.h"
#include "Polymer.h"
#include "Monomer.h"
#include "Thermostat.h"
#include "Rand.h"
#include <string>

const std::string Bussi::m_name = "Bussi";

Bussi::Bussi(Polymer &polymere, double timestep, double coupling_time)
	: Thermostat(polymere, timestep)
	, couplingtime(coupling_time)
{
	couplingtimeNfInverse = 1.0 / (couplingtime * m_poly.monomers.size());
	m_dtime_half = m_dtime * 0.5;
	cout << "CouplingInv" << couplingtimeNfInverse << endl << "Size" << m_poly.monomers.size();
}

void Bussi::propagate()
{
	//1. velocity verlet:
	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime_half * m.force / m_poly.monomer_mass;
		m.position += m_dtime * m.velocity;
	}
	m_poly.update_forces();
	for (auto& m : m_poly.monomers) m.velocity += m_dtime_half * m.force / m_poly.monomer_mass;

	//2. calculate target kinetic energy (as in the paper from bussi&donadio&parrinello)
	double ekin = m_poly.update_ekin();
	double wienernoise = Rand::real_normal(); // dW in the paper - N(0,1)
	double berendsen = (m_poly.target_temperature() - ekin)*m_dtime / couplingtime;
	double stochastic = 2.0* sqrt((ekin * m_poly.target_temperature()) * couplingtimeNfInverse) * wienernoise;
	double stoch_ekin = ekin + berendsen + stochastic; // evolve ekin with. stochastic dgl  (K_1 = K_0 + dK)

	//3. calculate scaling factor (as with gaussian thermostat)
	double scalingfactor;
	if (stoch_ekin > 0)
		scalingfactor = sqrt(stoch_ekin / ekin);
	else
		scalingfactor = -sqrt(-stoch_ekin / ekin);
	//4. rescale
	for (auto& m : m_poly.monomers) m.velocity *= scalingfactor;
}

void Bussi::update_temp() {
}

std::string Bussi::name() const { return m_name; }

std::string Bussi::info() const {
	std::string str{ "Thermostat " };
	str += m_name;
	str += " dtime ";
	str += std::to_string(m_dtime);
	str += " couplTime ";
	str += std::to_string(couplingtime);
	return str;
}
<|endoftext|>


<commit_before>#include "ProtocolManager.h"
#include "ProtocolInfo.h"
#include "ProtocolSpecification.h"

#include "common/GenericStore.h"
#include "Private/Constants.h"

#include <app/Roster.h>
#include <storage/VolumeRoster.h>
#include <storage/Volume.h>
#include <storage/Query.h>
#include <storage/Entry.h>
#include <support/Autolock.h>
#include <support/Locker.h>

#include <libim/Constants.h>
#include <libim/Helpers.h>

#include <map>

using namespace IM;

//#pragma mark Constants

const bigtime_t kQueryDelay = 5 * 1000 * 1000;	// 5 Seconds

class IM::ProtocolStore : public IM::GenericStore<BString, ProtocolInfo> {
};

//#pragma mark Constructor

ProtocolManager::ProtocolManager(void)
	: fProtocol(new ProtocolStore()),
	fLock(new BLocker("ProtocolManager")) {

	LOG("im_server", liHigh, "Finding ProtocolLoader with signature "IM_PROTOCOL_LOADER_SIG);

	entry_ref ref;
	if (be_roster->FindApp(IM_PROTOCOL_LOADER_SIG, &ref) != B_OK) {
		// Try with a query and take the first result
		BVolumeRoster vroster;
		BVolume volume;
		char volName[B_FILE_NAME_LENGTH];

		vroster.Rewind();

		while (vroster.GetNextVolume(&volume) == B_OK) {
			if ((volume.InitCheck() != B_OK) || (volume.KnowsQuery() == false))
				continue;

			volume.GetName(volName);
			LOG("im_server", liDebug, "ProtocolManager: Finding ProtocolLoader with a query on %s", volName);

			BQuery* query = new BQuery();
			query->SetPredicate("((BEOS:APP_SIG==\""IM_PROTOCOL_LOADER_SIG"\")&&(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
			query->SetVolume(&volume);
			query->Fetch();

			if (query->GetNextRef(&ref) == B_OK) {
				break;
			}

			LOG("im_server", liHigh, "Unable to find ProtocolLoader - waiting before retrying\n");
			snooze(kQueryDelay);

			if (query->GetNextRef(&ref) == B_OK) {
				break;
			};
		}
	}
	fLoaderPath = BPath(&ref);

	LOG("im_server", liHigh, "ProtocolLoader path: %s", fLoaderPath.Path());
};

ProtocolManager::~ProtocolManager(void) {
	delete fProtocol;
	delete fLock;
};

//#pragma mark Public

status_t ProtocolManager::LoadFromDirectory(BDirectory protocols, BDirectory settings) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		BPath path((const BDirectory *)&protocols, NULL, false);
		LOG("im_server", liMedium, "ProtocolManager::LoadFromDirectory called - %s", path.Path());

		BEntry entry;
		protocols.Rewind();

		while (protocols.GetNextEntry((BEntry*)&entry, true) == B_NO_ERROR) {
			// continue until no more files
			if (entry.InitCheck() != B_NO_ERROR) continue;

			BPath addonPath;
			entry.GetPath(&addonPath);
			BPath settingsPath(&settings, addonPath.Leaf());

			BMessage accounts;
			BString account;
			im_protocol_get_account_list(addonPath.Leaf(), &accounts);

			for (int32 i = 0; accounts.FindString("account", i, &account) == B_OK; i++) {
				entry_ref accountSettings;

				if (accounts.FindRef("settings_path", i, &accountSettings) != B_OK) {
					LOG("im_server", liHigh, "%s - %s does not have a settings path", settingsPath.Leaf(), account.String());
					continue;
				};

				BPath accountSettingsPath(&accountSettings);
				ProtocolInfo *info = new ProtocolInfo(addonPath, accountSettingsPath, account.String());
				fProtocol->Add(info->InstanceID(), info);

				LOG("im_server", liMedium, "Loading protocol from %s (%s): %s", fLoaderPath.Path(), settingsPath.Path(), account.String());
				info->Start(fLoaderPath.Path());
			};
		};
	};

	return result;
};

status_t ProtocolManager::RestartProtocols(ProtocolSpecification *match, bool canDelete = true) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++){
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				info->Start(fLoaderPath.Path());
			};
		};

		result = B_OK;
	};

	if (canDelete == true) delete match;

	return result;
};

status_t ProtocolManager::Unload(void) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;
		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;

			if (info->HasValidMessenger() == true) {
				info->Messenger()->SendMessage(B_QUIT_REQUESTED);
			} else {
				// A half loaded addon - force it to exit
				kill_thread(info->ThreadID());
			};
		};

		// Give all the protocols a chance to shutdown
		snooze(20000);

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;
			status_t exitValue = B_ERROR;

			status_t result = wait_for_thread(info->ThreadID(), &exitValue);

			LOG("im_server", liMedium, "Protocol %s/%s: Exiting - %s: %s (%i)", info->Path().Leaf(),
				info->SettingsPath().Leaf(), strerror(result), strerror(exitValue), exitValue);
		}

		fProtocol->Clear();
		result = B_OK;
	};

	return result;
};

status_t ProtocolManager::MessageProtocols(ProtocolSpecification *match, BMessage *message, bool canDelete = true, bool appendSignature = true) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++){
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				BMessage copy(*message);
				if (appendSignature == true) copy.AddString("protocol", info->Signature());

				info->Process(&copy);

				result = B_OK;
			};
		};
	};

	if (canDelete == true) delete match;

	return result;
};

ProtocolInfo *ProtocolManager::FindFirstProtocol(ProtocolSpecification *match, bool canDelete = true) {
	ProtocolInfo *info = NULL;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *cur = it->second;

			if (match->IsSatisfiedBy(cur) == true) {
				info = cur;
				break;
			};
		};
	};

	if (canDelete == true) delete match;

	return info;
};

list<ProtocolInfo *> ProtocolManager::FindProtocols(ProtocolSpecification *match, bool canDelete = true) {
	list<ProtocolInfo *> protocols;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				protocols.push_back(info);
			};
		};
	};

	if (canDelete == true) delete match;

	return protocols;
};

//#pragma mark Private
<commit_msg>Remove extra \n at the end of the log message.<commit_after>#include "ProtocolManager.h"
#include "ProtocolInfo.h"
#include "ProtocolSpecification.h"

#include "common/GenericStore.h"
#include "Private/Constants.h"

#include <app/Roster.h>
#include <storage/VolumeRoster.h>
#include <storage/Volume.h>
#include <storage/Query.h>
#include <storage/Entry.h>
#include <support/Autolock.h>
#include <support/Locker.h>

#include <libim/Constants.h>
#include <libim/Helpers.h>

#include <map>

using namespace IM;

//#pragma mark Constants

const bigtime_t kQueryDelay = 5 * 1000 * 1000;	// 5 Seconds

class IM::ProtocolStore : public IM::GenericStore<BString, ProtocolInfo> {
};

//#pragma mark Constructor

ProtocolManager::ProtocolManager(void)
	: fProtocol(new ProtocolStore()),
	fLock(new BLocker("ProtocolManager")) {

	LOG("im_server", liHigh, "Finding ProtocolLoader with signature "IM_PROTOCOL_LOADER_SIG);

	entry_ref ref;
	if (be_roster->FindApp(IM_PROTOCOL_LOADER_SIG, &ref) != B_OK) {
		// Try with a query and take the first result
		BVolumeRoster vroster;
		BVolume volume;
		char volName[B_FILE_NAME_LENGTH];

		vroster.Rewind();

		while (vroster.GetNextVolume(&volume) == B_OK) {
			if ((volume.InitCheck() != B_OK) || (volume.KnowsQuery() == false))
				continue;

			volume.GetName(volName);
			LOG("im_server", liDebug, "ProtocolManager: Finding ProtocolLoader with a query on %s", volName);

			BQuery* query = new BQuery();
			query->SetPredicate("((BEOS:APP_SIG==\""IM_PROTOCOL_LOADER_SIG"\")&&(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))");
			query->SetVolume(&volume);
			query->Fetch();

			if (query->GetNextRef(&ref) == B_OK) {
				break;
			}

			LOG("im_server", liHigh, "Unable to find ProtocolLoader - waiting before retrying");
			snooze(kQueryDelay);

			if (query->GetNextRef(&ref) == B_OK) {
				break;
			};
		}
	}
	fLoaderPath = BPath(&ref);

	LOG("im_server", liHigh, "ProtocolLoader path: %s", fLoaderPath.Path());
};

ProtocolManager::~ProtocolManager(void) {
	delete fProtocol;
	delete fLock;
};

//#pragma mark Public

status_t ProtocolManager::LoadFromDirectory(BDirectory protocols, BDirectory settings) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		BPath path((const BDirectory *)&protocols, NULL, false);
		LOG("im_server", liMedium, "ProtocolManager::LoadFromDirectory called - %s", path.Path());

		BEntry entry;
		protocols.Rewind();

		while (protocols.GetNextEntry((BEntry*)&entry, true) == B_NO_ERROR) {
			// continue until no more files
			if (entry.InitCheck() != B_NO_ERROR) continue;

			BPath addonPath;
			entry.GetPath(&addonPath);
			BPath settingsPath(&settings, addonPath.Leaf());

			BMessage accounts;
			BString account;
			im_protocol_get_account_list(addonPath.Leaf(), &accounts);

			for (int32 i = 0; accounts.FindString("account", i, &account) == B_OK; i++) {
				entry_ref accountSettings;

				if (accounts.FindRef("settings_path", i, &accountSettings) != B_OK) {
					LOG("im_server", liHigh, "%s - %s does not have a settings path", settingsPath.Leaf(), account.String());
					continue;
				};

				BPath accountSettingsPath(&accountSettings);
				ProtocolInfo *info = new ProtocolInfo(addonPath, accountSettingsPath, account.String());
				fProtocol->Add(info->InstanceID(), info);

				LOG("im_server", liMedium, "Loading protocol from %s (%s): %s", fLoaderPath.Path(), settingsPath.Path(), account.String());
				info->Start(fLoaderPath.Path());
			};
		};
	};

	return result;
};

status_t ProtocolManager::RestartProtocols(ProtocolSpecification *match, bool canDelete = true) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++){
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				info->Start(fLoaderPath.Path());
			};
		};

		result = B_OK;
	};

	if (canDelete == true) delete match;

	return result;
};

status_t ProtocolManager::Unload(void) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;
		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;

			if (info->HasValidMessenger() == true) {
				info->Messenger()->SendMessage(B_QUIT_REQUESTED);
			} else {
				// A half loaded addon - force it to exit
				kill_thread(info->ThreadID());
			};
		};

		// Give all the protocols a chance to shutdown
		snooze(20000);

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;
			status_t exitValue = B_ERROR;

			status_t result = wait_for_thread(info->ThreadID(), &exitValue);

			LOG("im_server", liMedium, "Protocol %s/%s: Exiting - %s: %s (%i)", info->Path().Leaf(),
				info->SettingsPath().Leaf(), strerror(result), strerror(exitValue), exitValue);
		}

		fProtocol->Clear();
		result = B_OK;
	};

	return result;
};

status_t ProtocolManager::MessageProtocols(ProtocolSpecification *match, BMessage *message, bool canDelete = true, bool appendSignature = true) {
	status_t result = B_ERROR;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++){
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				BMessage copy(*message);
				if (appendSignature == true) copy.AddString("protocol", info->Signature());

				info->Process(&copy);

				result = B_OK;
			};
		};
	};

	if (canDelete == true) delete match;

	return result;
};

ProtocolInfo *ProtocolManager::FindFirstProtocol(ProtocolSpecification *match, bool canDelete = true) {
	ProtocolInfo *info = NULL;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *cur = it->second;

			if (match->IsSatisfiedBy(cur) == true) {
				info = cur;
				break;
			};
		};
	};

	if (canDelete == true) delete match;

	return info;
};

list<ProtocolInfo *> ProtocolManager::FindProtocols(ProtocolSpecification *match, bool canDelete = true) {
	list<ProtocolInfo *> protocols;
	BAutolock lock(fLock);

	if (lock.IsLocked() == true) {
		map<BString, ProtocolInfo *>::iterator it;

		for (it = fProtocol->Start(); it != fProtocol->End(); it++) {
			ProtocolInfo *info = it->second;

			if (match->IsSatisfiedBy(info) == true) {
				protocols.push_back(info);
			};
		};
	};

	if (canDelete == true) delete match;

	return protocols;
};

//#pragma mark Private
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Stephan Vedder <stefano.pigozzi@gmail.com>
 *
 * This file is part of libass.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "config.h"

#ifdef CONFIG_DIRECTWRITE

#include <dwrite.h>

extern "C"
{
#include "ass_directwrite.h"
#include "ass_utils.h"
}

typedef struct {
	IDWriteFont *font;
	IDWriteFontFileStream *stream;
} FontPrivate;

static bool init_font_private(FontPrivate *priv)
{
	HRESULT hr = S_OK;
	IDWriteFont* font = priv->font;
	IDWriteFontFace* face = NULL;
	IDWriteFontFile* file = NULL;
	IDWriteFontFileStream* stream = NULL;
	IDWriteFontFileLoader* loader = NULL;
	UINT32 n_files = 1;
	const void* refKey = NULL;
	UINT32 keySize = 0;

	if (priv->stream != NULL)
		return true;

	hr = font->CreateFontFace(&face);
	if (FAILED(hr) || !face)
		return false;

	hr = face->GetFiles(&n_files, &file);
	if (FAILED(hr) || !file) {
		face->Release();
		return false;
	}

	hr = file->GetReferenceKey(&refKey, &keySize);
	if (FAILED(hr)) {
		file->Release();
		face->Release();
		return false;
	}

	hr = file->GetLoader(&loader);
	if (FAILED(hr) || !loader) {
		file->Release();
		face->Release();
		return false;
	}

	hr = loader->CreateStreamFromKey(refKey, keySize, &stream);
	if (FAILED(hr) || !stream) {
		file->Release();
		face->Release();
		return false;
	}

	priv->stream = stream;
	file->Release();
	face->Release();

	return true;
}

static size_t get_data(void *data, unsigned char* buf, size_t offset, size_t length)
{
	HRESULT hr = S_OK;
	FontPrivate *priv = (FontPrivate *)data;
	const void *fileBuf = NULL;
	void *fragContext = NULL;

	if (!init_font_private(priv))
		return 0;

	if (buf == NULL) {
		UINT64 fileSize;
		hr = priv->stream->GetFileSize(&fileSize);
		if (FAILED(hr))
			return 0;

		return fileSize;
	}

	hr = priv->stream->ReadFileFragment(&fileBuf, offset, length, &fragContext);
	if (FAILED(hr) || !fileBuf)
		return 0;

	memcpy(buf, fileBuf, length);

	priv->stream->ReleaseFileFragment(fragContext);

	return length;
}

static int check_glyph(void *data, uint32_t code)
{
	HRESULT hr = S_OK;
	FontPrivate *priv = (FontPrivate *)data;
	BOOL exists = FALSE;

	if (code == 0)
		return 1;

	priv->font->HasCharacter(code, &exists);
	if (FAILED(hr))
		return 0;

	return exists;
}

static void destroy_provider(void *priv)
{
	((IDWriteFactory*)priv)->Release();
}

static void destroy_font(void *data)
{
	FontPrivate *priv = (FontPrivate *)data;

	priv->font->Release();
	if (priv->stream != NULL)
		priv->stream->Release();

	free(priv);
}

static int map_width(int stretch)
{
	return stretch * (100 / DWRITE_FONT_STRETCH_MEDIUM);
}

static void scan_fonts(IDWriteFactory *factory, ASS_FontProvider *provider)
{
	HRESULT hr = S_OK;
	IDWriteFontCollection* fontCollection = NULL;
	IDWriteFont* font = NULL;
	DWRITE_FONT_METRICS metrics;
	DWRITE_FONT_STYLE style;
	ASS_FontProviderMetaData meta = ASS_FontProviderMetaData();
	hr = factory->GetSystemFontCollection(&fontCollection,FALSE);
	wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
	int size_needed = 0;

	if(FAILED(hr)||!fontCollection)
		return;

	UINT32 familyCount = fontCollection->GetFontFamilyCount();

	for (UINT32 i = 0; i < familyCount; ++i)
    {
		IDWriteFontFamily* fontFamily = NULL;
		IDWriteLocalizedStrings* familyNames = NULL;
		IDWriteLocalizedStrings* fontNames = NULL;
		IDWriteLocalizedStrings* psNames = NULL;
		BOOL exists = FALSE;
		char* psName = NULL;

		// Get the font family.
		hr = fontCollection->GetFontFamily(i, &fontFamily);
		if (FAILED(hr))
			return;

		UINT32 fontCount = fontFamily->GetFontCount();
		for (UINT32 j = 0; j < fontCount; ++j)
		{
			hr = fontFamily->GetFont(j, &font);
			if (FAILED(hr))
				return;

			meta.weight = font->GetWeight();
			meta.width = map_width(font->GetStretch());
			font->GetMetrics(&metrics);
			style = font->GetStyle();
			meta.slant =	(style==DWRITE_FONT_STYLE_NORMAL)? FONT_SLANT_NONE:
							(style==DWRITE_FONT_STYLE_OBLIQUE)? FONT_SLANT_OBLIQUE:
							(style==DWRITE_FONT_STYLE_ITALIC)? FONT_SLANT_ITALIC : FONT_SLANT_NONE;

			hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames, &exists);
			if (FAILED(hr))
				return;

			if (exists)
			{
				hr = psNames->GetString(0, localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				psName = (char*)ass_aligned_alloc(32, size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, psName, size_needed, NULL, NULL);
			}

			hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames, &exists);
			if (FAILED(hr))
				return;

			meta.n_fullname = fontNames->GetCount();
			meta.fullnames = (char **)calloc(meta.n_fullname, sizeof(char *));
			for (UINT32 k = 0; k < meta.n_fullname; ++k)
			{
				hr = fontNames->GetString(k,localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				char* mbName = (char *)malloc(size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
				meta.fullnames[k] = mbName;
			}

			hr = fontFamily->GetFamilyNames(&familyNames);
			if (FAILED(hr))
				return;

			meta.n_family = familyNames->GetCount();
			meta.families = (char **)calloc(meta.n_family, sizeof(char *));
			for (UINT32 k = 0; k < meta.n_family; ++k)
			{
				hr = familyNames->GetString(k, localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				char* mbName = (char *)malloc(size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
				meta.families[k] = mbName;
			}

			FontPrivate *font_priv = (FontPrivate *)calloc(1, sizeof(*font_priv));
			font_priv->font = font;

			ass_font_provider_add_font(provider, &meta, NULL, 0, psName, font_priv);

			for (UINT32 k = 0; k < meta.n_family; ++k)
				free(meta.families[k]);
			for (UINT32 k = 0; k < meta.n_fullname; ++k)
				free(meta.fullnames[k]);
			free(meta.fullnames);
			free(meta.families);
			free(psName);
		}
    }
}

static ASS_FontProviderFuncs directwrite_callbacks = {
    get_data,
	check_glyph,
    destroy_font,
    destroy_provider,
    NULL,
};

ASS_FontProvider *
ass_directwrite_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
                          const char *config)
{
	HRESULT hr = S_OK;
	IDWriteFactory* dwFactory = NULL;
	ASS_FontProvider *provider = NULL;

	hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            (IUnknown**)(&dwFactory));

	if(FAILED(hr))
	{
		ass_msg(lib, MSGL_WARN, "Failed to initialize directwrite.");
		goto exit;
	}

    provider = ass_font_provider_new(selector, &directwrite_callbacks, dwFactory);

    scan_fonts(dwFactory,provider);
exit:
    return provider;
}

#endif
<commit_msg>directwrite: use standard malloc<commit_after>/*
 * Copyright (C) 2015 Stephan Vedder <stefano.pigozzi@gmail.com>
 *
 * This file is part of libass.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "config.h"

#ifdef CONFIG_DIRECTWRITE

#include <dwrite.h>

extern "C"
{
#include "ass_directwrite.h"
#include "ass_utils.h"
}

typedef struct {
	IDWriteFont *font;
	IDWriteFontFileStream *stream;
} FontPrivate;

static bool init_font_private(FontPrivate *priv)
{
	HRESULT hr = S_OK;
	IDWriteFont* font = priv->font;
	IDWriteFontFace* face = NULL;
	IDWriteFontFile* file = NULL;
	IDWriteFontFileStream* stream = NULL;
	IDWriteFontFileLoader* loader = NULL;
	UINT32 n_files = 1;
	const void* refKey = NULL;
	UINT32 keySize = 0;

	if (priv->stream != NULL)
		return true;

	hr = font->CreateFontFace(&face);
	if (FAILED(hr) || !face)
		return false;

	hr = face->GetFiles(&n_files, &file);
	if (FAILED(hr) || !file) {
		face->Release();
		return false;
	}

	hr = file->GetReferenceKey(&refKey, &keySize);
	if (FAILED(hr)) {
		file->Release();
		face->Release();
		return false;
	}

	hr = file->GetLoader(&loader);
	if (FAILED(hr) || !loader) {
		file->Release();
		face->Release();
		return false;
	}

	hr = loader->CreateStreamFromKey(refKey, keySize, &stream);
	if (FAILED(hr) || !stream) {
		file->Release();
		face->Release();
		return false;
	}

	priv->stream = stream;
	file->Release();
	face->Release();

	return true;
}

static size_t get_data(void *data, unsigned char* buf, size_t offset, size_t length)
{
	HRESULT hr = S_OK;
	FontPrivate *priv = (FontPrivate *)data;
	const void *fileBuf = NULL;
	void *fragContext = NULL;

	if (!init_font_private(priv))
		return 0;

	if (buf == NULL) {
		UINT64 fileSize;
		hr = priv->stream->GetFileSize(&fileSize);
		if (FAILED(hr))
			return 0;

		return fileSize;
	}

	hr = priv->stream->ReadFileFragment(&fileBuf, offset, length, &fragContext);
	if (FAILED(hr) || !fileBuf)
		return 0;

	memcpy(buf, fileBuf, length);

	priv->stream->ReleaseFileFragment(fragContext);

	return length;
}

static int check_glyph(void *data, uint32_t code)
{
	HRESULT hr = S_OK;
	FontPrivate *priv = (FontPrivate *)data;
	BOOL exists = FALSE;

	if (code == 0)
		return 1;

	priv->font->HasCharacter(code, &exists);
	if (FAILED(hr))
		return 0;

	return exists;
}

static void destroy_provider(void *priv)
{
	((IDWriteFactory*)priv)->Release();
}

static void destroy_font(void *data)
{
	FontPrivate *priv = (FontPrivate *)data;

	priv->font->Release();
	if (priv->stream != NULL)
		priv->stream->Release();

	free(priv);
}

static int map_width(int stretch)
{
	return stretch * (100 / DWRITE_FONT_STRETCH_MEDIUM);
}

static void scan_fonts(IDWriteFactory *factory, ASS_FontProvider *provider)
{
	HRESULT hr = S_OK;
	IDWriteFontCollection* fontCollection = NULL;
	IDWriteFont* font = NULL;
	DWRITE_FONT_METRICS metrics;
	DWRITE_FONT_STYLE style;
	ASS_FontProviderMetaData meta = ASS_FontProviderMetaData();
	hr = factory->GetSystemFontCollection(&fontCollection,FALSE);
	wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
	int size_needed = 0;

	if(FAILED(hr)||!fontCollection)
		return;

	UINT32 familyCount = fontCollection->GetFontFamilyCount();

	for (UINT32 i = 0; i < familyCount; ++i)
    {
		IDWriteFontFamily* fontFamily = NULL;
		IDWriteLocalizedStrings* familyNames = NULL;
		IDWriteLocalizedStrings* fontNames = NULL;
		IDWriteLocalizedStrings* psNames = NULL;
		BOOL exists = FALSE;
		char* psName = NULL;

		// Get the font family.
		hr = fontCollection->GetFontFamily(i, &fontFamily);
		if (FAILED(hr))
			return;

		UINT32 fontCount = fontFamily->GetFontCount();
		for (UINT32 j = 0; j < fontCount; ++j)
		{
			hr = fontFamily->GetFont(j, &font);
			if (FAILED(hr))
				return;

			meta.weight = font->GetWeight();
			meta.width = map_width(font->GetStretch());
			font->GetMetrics(&metrics);
			style = font->GetStyle();
			meta.slant =	(style==DWRITE_FONT_STYLE_NORMAL)? FONT_SLANT_NONE:
							(style==DWRITE_FONT_STYLE_OBLIQUE)? FONT_SLANT_OBLIQUE:
							(style==DWRITE_FONT_STYLE_ITALIC)? FONT_SLANT_ITALIC : FONT_SLANT_NONE;

			hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames, &exists);
			if (FAILED(hr))
				return;

			if (exists)
			{
				hr = psNames->GetString(0, localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				psName = (char*)malloc(size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, psName, size_needed, NULL, NULL);
			}

			hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames, &exists);
			if (FAILED(hr))
				return;

			meta.n_fullname = fontNames->GetCount();
			meta.fullnames = (char **)calloc(meta.n_fullname, sizeof(char *));
			for (UINT32 k = 0; k < meta.n_fullname; ++k)
			{
				hr = fontNames->GetString(k,localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				char* mbName = (char *)malloc(size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
				meta.fullnames[k] = mbName;
			}

			hr = fontFamily->GetFamilyNames(&familyNames);
			if (FAILED(hr))
				return;

			meta.n_family = familyNames->GetCount();
			meta.families = (char **)calloc(meta.n_family, sizeof(char *));
			for (UINT32 k = 0; k < meta.n_family; ++k)
			{
				hr = familyNames->GetString(k, localeName, LOCALE_NAME_MAX_LENGTH + 1);
				if (FAILED(hr))
					return;

				size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
				char* mbName = (char *)malloc(size_needed);
				WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
				meta.families[k] = mbName;
			}

			FontPrivate *font_priv = (FontPrivate *)calloc(1, sizeof(*font_priv));
			font_priv->font = font;

			ass_font_provider_add_font(provider, &meta, NULL, 0, psName, font_priv);

			for (UINT32 k = 0; k < meta.n_family; ++k)
				free(meta.families[k]);
			for (UINT32 k = 0; k < meta.n_fullname; ++k)
				free(meta.fullnames[k]);
			free(meta.fullnames);
			free(meta.families);
			free(psName);
		}
    }
}

static ASS_FontProviderFuncs directwrite_callbacks = {
    get_data,
	check_glyph,
    destroy_font,
    destroy_provider,
    NULL,
};

ASS_FontProvider *
ass_directwrite_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
                          const char *config)
{
	HRESULT hr = S_OK;
	IDWriteFactory* dwFactory = NULL;
	ASS_FontProvider *provider = NULL;

	hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            (IUnknown**)(&dwFactory));

	if(FAILED(hr))
	{
		ass_msg(lib, MSGL_WARN, "Failed to initialize directwrite.");
		goto exit;
	}

    provider = ass_font_provider_new(selector, &directwrite_callbacks, dwFactory);

    scan_fonts(dwFactory,provider);
exit:
    return provider;
}

#endif
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_DETAIL_LOGGING_HPP
#define CAF_DETAIL_LOGGING_HPP

#include <thread>
#include <cstring>
#include <sstream>
#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <unordered_map>

#include "caf/fwd.hpp"
#include "caf/config.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/deep_to_string.hpp"

#include "caf/detail/type_nr.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
#include "caf/detail/single_reader_queue.hpp"

/*
 * To enable logging, you have to define CAF_DEBUG. This enables
 * CAF_LOG_ERROR messages. To enable more debugging output, you can
 * define CAF_LOG_LEVEL to:
 * 1: + warning
 * 2: + info
 * 3: + debug
 * 4: + trace (prints for each logged method entry and exit message)
 *
 * Note: this logger emits log4j style output; logs are best viewed
 *       using a log4j viewer, e.g., http://code.google.com/p/otroslogviewer/
 *
 */
namespace caf {

/// Centrally logs events from all actors in an actor system. To enable
/// logging in your application, you need to define `CAF_LOG_LEVEL`. Per
/// default, the logger generates log4j compatible output.
class logger {
public:
  friend class actor_system;

  struct event {
    event* next;
    event* prev;
    std::string msg;
    explicit event(std::string log_message = "");
  };

  template <class T>
  struct arg_wrapper {
    const char* name;
    const T& value;
    arg_wrapper(const char* x, const T& y) : name(x), value(y) {
      // nop
    }
  };

  template <class T>
  static arg_wrapper<T> make_arg_wrapper(const char* name, const T& value) {
    return {name, value};
  }

  static std::string render_type_name(const std::type_info& ti);

  class line_builder {
  public:
    line_builder();

    template <class T>
    line_builder& operator<<(const arg_wrapper<T>& x) {
      if (behind_arg_)
        str_ += ", ";
      else if (! str_.empty())
        str_ += " ";
      str_ += x.name;
      str_ += " = ";
      str_ += deep_to_string(x.value);
      behind_arg_ = true;
      return *this;
    }

    line_builder& operator<<(const char* str);

    std::string get() const;

  private:
    std::string str_;
    bool behind_arg_;
  };

  static std::string extract_class_name(const char* prettyfun, size_t strsize);

  template <size_t N>
  static std::string extract_class_name(const char (&prettyfun)[N]) {
    return extract_class_name(prettyfun, N);
  }

  /// Returns the ID of the actor currently associated to the calling thread.
  actor_id thread_local_aid();

  /// Associates an actor ID to the calling thread and returns the last value.
  actor_id thread_local_aid(actor_id aid);

  /// Writes an entry to the log file.
  void log(int level, const std::string& class_name,
           const char* function_name, const char* file_name,
           int line_num, const std::string& msg);

  ~logger();

  /** @cond PRIVATE */

  class trace_helper {
  public:
    trace_helper(std::string class_name, const char* fun_name,
                 const char* file_name, int line_num, const std::string& msg);

    ~trace_helper();

  private:
    logger* parent_;
    std::string class_;
    const char* fun_name_;
    const char* file_name_;
    int line_num_;
  };

  static void set_current_actor_system(actor_system*);

  static logger* current_logger();

  static void log_static(int level, const std::string& class_name,
                         const char* function_name, const char* file_name,
                         int line_num, const std::string& msg);

  /** @endcond */

private:
  logger(actor_system& sys);

  void run();

  void start();

  void stop();

  actor_system& system_;
  detail::shared_spinlock aids_lock_;
  std::unordered_map<std::thread::id, actor_id> aids_;
  std::thread thread_;
  std::mutex queue_mtx_;
  std::condition_variable queue_cv_;
  detail::single_reader_queue<event> queue_;
};

} // namespace caf

#define CAF_VOID_STMT static_cast<void>(0)

#define CAF_CAT(a, b) a##b

#define CAF_LOG_LEVEL_ERROR 0
#define CAF_LOG_LEVEL_WARNING 1
#define CAF_LOG_LEVEL_INFO 2
#define CAF_LOG_LEVEL_DEBUG 3
#define CAF_LOG_LEVEL_TRACE 4

#define CAF_CONCAT_(LHS, RHS) LHS ## RHS
#define CAF_CONCAT(LHS, RHS) CAF_CONCAT_(LHS, RHS)
#define CAF_UNIFYN(NAME) CAF_CONCAT(NAME, __LINE__)

#define CAF_PRINT_ERROR_IMPL(nclass, nfun, message)                            \
  do {                                                                         \
    caf::logger::line_builder lb;                                              \
    lb << message;                                                             \
    if (nclass.empty())                                                        \
      printf("[ERROR] %s::%s: %s\n", nclass.c_str(), nfun, lb.get().c_str());  \
    else                                                                       \
      printf("[ERROR] %s: %s\n", nfun, lb.get().c_str());                      \
  } while (false)

#define CAF_ARG(argument) caf::logger::make_arg_wrapper(#argument, argument)

#ifdef CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__FUNCSIG__)
#else // CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__PRETTY_FUNCTION__)
#endif // CAF_MSVC

#ifndef CAF_LOG_LEVEL

#define CAF_LOG_IMPL(unused1, unused2)

// placeholder macros when compiling without logging
inline caf::actor_id caf_set_aid_dummy() { return 0; }

#define CAF_PUSH_AID(unused) CAF_VOID_STMT

#define CAF_PUSH_AID_FROM_PTR(unused) CAF_VOID_STMT

#define CAF_SET_AID(unused) caf_set_aid_dummy()

#define CAF_SET_LOGGER_SYS(unused) CAF_VOID_STMT

#define CAF_LOG_TRACE(unused)

#else // CAF_LOG_LEVEL

#define CAF_LOG_IMPL(loglvl, message)                                          \
  caf::logger::log_static(loglvl, CAF_GET_CLASS_NAME, __func__,                \
                          __FILE__, __LINE__,                                  \
                          (caf::logger::line_builder{} << message).get())

#define CAF_PUSH_AID(aarg)                                                     \
  auto CAF_UNIFYN(caf_tmp_ptr) = caf::logger::current_logger();                \
  caf::actor_id CAF_UNIFYN(caf_aid_tmp) = 0;                                   \
  if (CAF_UNIFYN(caf_tmp_ptr))                                                 \
    CAF_UNIFYN(caf_aid_tmp) = CAF_UNIFYN(caf_tmp_ptr)->thread_local_aid(aarg); \
  else                                                                         \
    printf("[ERROR] CAF_PUSH_AID called in file %s on line %d "                \
           "without thread-local logger pointer", __FILE__, __LINE__);         \
  auto CAF_UNIFYN(aid_aid_tmp_guard) = caf::detail::make_scope_guard([=] {     \
    auto CAF_UNIFYN(caf_tmp2_ptr) = caf::logger::current_logger();             \
    if (CAF_UNIFYN(caf_tmp2_ptr))                                              \
      CAF_UNIFYN(caf_tmp2_ptr)->thread_local_aid(CAF_UNIFYN(caf_aid_tmp));     \
  })

#define CAF_PUSH_AID_FROM_PTR(some_ptr)                                        \
  auto CAF_UNIFYN(caf_aid_ptr) = some_ptr;                                     \
  CAF_PUSH_AID(CAF_UNIFYN(caf_aid_ptr) ? CAF_UNIFYN(caf_aid_ptr)->id() : 0)

#define CAF_SET_AID(aid_arg)                                                   \
  (caf::logger::current_logger()                                               \
     ? caf::logger::current_logger()->thread_local_aid(aid_arg)                \
     : 0)

#define CAF_SET_LOGGER_SYS(ptr) caf::logger::set_current_actor_system(ptr)

#if CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(unused) CAF_VOID_STMT

#else // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(entry_message)                                           \
  caf::logger::trace_helper CAF_UNIFYN(caf_log_trace_) {                       \
    CAF_GET_CLASS_NAME, __func__, __FILE__, __LINE__,                          \
    (caf::logger::line_builder{} << entry_message).get()                       \
  }

#endif // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#endif // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output)
#define CAF_LOG_INFO(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output)
#define CAF_LOG_WARNING(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output)
#define CAF_LOG_ERROR(output)                                                  \
  do {                                                                         \
    CAF_PRINT_ERROR_IMPL(CAF_GET_CLASS_NAME, __func__, output);                \
    CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output);                                 \
  } while (false)

#ifdef CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output); } CAF_VOID_STMT

#define CAF_LOG_INFO_IF(cond, output)                                          \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output); } CAF_VOID_STMT

#define CAF_LOG_WARNING_IF(cond, output)                                       \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output); } CAF_VOID_STMT

#define CAF_LOG_ERROR_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output); } CAF_VOID_STMT

#else // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(unused1, unused2)
#define CAF_LOG_INFO_IF(unused1, unused2)
#define CAF_LOG_WARNING_IF(unused1, unused2)
#define CAF_LOG_ERROR_IF(unused1, unused2)

#endif // CAF_LOG_LEVEL

#endif // CAF_DETAIL_LOGGING_HPP
<commit_msg>Print file and line number on errors<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2015                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_DETAIL_LOGGING_HPP
#define CAF_DETAIL_LOGGING_HPP

#include <thread>
#include <cstring>
#include <sstream>
#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <unordered_map>

#include "caf/fwd.hpp"
#include "caf/config.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/deep_to_string.hpp"

#include "caf/detail/type_nr.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
#include "caf/detail/single_reader_queue.hpp"

/*
 * To enable logging, you have to define CAF_DEBUG. This enables
 * CAF_LOG_ERROR messages. To enable more debugging output, you can
 * define CAF_LOG_LEVEL to:
 * 1: + warning
 * 2: + info
 * 3: + debug
 * 4: + trace (prints for each logged method entry and exit message)
 *
 * Note: this logger emits log4j style output; logs are best viewed
 *       using a log4j viewer, e.g., http://code.google.com/p/otroslogviewer/
 *
 */
namespace caf {

/// Centrally logs events from all actors in an actor system. To enable
/// logging in your application, you need to define `CAF_LOG_LEVEL`. Per
/// default, the logger generates log4j compatible output.
class logger {
public:
  friend class actor_system;

  struct event {
    event* next;
    event* prev;
    std::string msg;
    explicit event(std::string log_message = "");
  };

  template <class T>
  struct arg_wrapper {
    const char* name;
    const T& value;
    arg_wrapper(const char* x, const T& y) : name(x), value(y) {
      // nop
    }
  };

  template <class T>
  static arg_wrapper<T> make_arg_wrapper(const char* name, const T& value) {
    return {name, value};
  }

  static std::string render_type_name(const std::type_info& ti);

  class line_builder {
  public:
    line_builder();

    template <class T>
    line_builder& operator<<(const arg_wrapper<T>& x) {
      if (behind_arg_)
        str_ += ", ";
      else if (! str_.empty())
        str_ += " ";
      str_ += x.name;
      str_ += " = ";
      str_ += deep_to_string(x.value);
      behind_arg_ = true;
      return *this;
    }

    line_builder& operator<<(const char* str);

    std::string get() const;

  private:
    std::string str_;
    bool behind_arg_;
  };

  static std::string extract_class_name(const char* prettyfun, size_t strsize);

  template <size_t N>
  static std::string extract_class_name(const char (&prettyfun)[N]) {
    return extract_class_name(prettyfun, N);
  }

  /// Returns the ID of the actor currently associated to the calling thread.
  actor_id thread_local_aid();

  /// Associates an actor ID to the calling thread and returns the last value.
  actor_id thread_local_aid(actor_id aid);

  /// Writes an entry to the log file.
  void log(int level, const std::string& class_name,
           const char* function_name, const char* file_name,
           int line_num, const std::string& msg);

  ~logger();

  /** @cond PRIVATE */

  class trace_helper {
  public:
    trace_helper(std::string class_name, const char* fun_name,
                 const char* file_name, int line_num, const std::string& msg);

    ~trace_helper();

  private:
    logger* parent_;
    std::string class_;
    const char* fun_name_;
    const char* file_name_;
    int line_num_;
  };

  static void set_current_actor_system(actor_system*);

  static logger* current_logger();

  static void log_static(int level, const std::string& class_name,
                         const char* function_name, const char* file_name,
                         int line_num, const std::string& msg);

  /** @endcond */

private:
  logger(actor_system& sys);

  void run();

  void start();

  void stop();

  actor_system& system_;
  detail::shared_spinlock aids_lock_;
  std::unordered_map<std::thread::id, actor_id> aids_;
  std::thread thread_;
  std::mutex queue_mtx_;
  std::condition_variable queue_cv_;
  detail::single_reader_queue<event> queue_;
};

} // namespace caf

#define CAF_VOID_STMT static_cast<void>(0)

#define CAF_CAT(a, b) a##b

#define CAF_LOG_LEVEL_ERROR 0
#define CAF_LOG_LEVEL_WARNING 1
#define CAF_LOG_LEVEL_INFO 2
#define CAF_LOG_LEVEL_DEBUG 3
#define CAF_LOG_LEVEL_TRACE 4

#define CAF_CONCAT_(LHS, RHS) LHS ## RHS
#define CAF_CONCAT(LHS, RHS) CAF_CONCAT_(LHS, RHS)
#define CAF_UNIFYN(NAME) CAF_CONCAT(NAME, __LINE__)

#define CAF_PRINT_ERROR_IMPL(nclass, nfun, message)                            \
  do {                                                                         \
    caf::logger::line_builder lb;                                              \
    lb << message;                                                             \
    if (nclass.empty())                                                        \
      printf("[ERROR] in %s:%d %s::%s: %s\n", __FILE__, __LINE__,              \
             nclass.c_str(), nfun, lb.get().c_str());                          \
    else                                                                       \
      printf("[ERROR] in %s:%d %s: %s\n", __FILE__, __LINE__,                  \
             nfun, lb.get().c_str());                      \
  } while (false)

#define CAF_ARG(argument) caf::logger::make_arg_wrapper(#argument, argument)

#ifdef CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__FUNCSIG__)
#else // CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__PRETTY_FUNCTION__)
#endif // CAF_MSVC

#ifndef CAF_LOG_LEVEL

#define CAF_LOG_IMPL(unused1, unused2)

// placeholder macros when compiling without logging
inline caf::actor_id caf_set_aid_dummy() { return 0; }

#define CAF_PUSH_AID(unused) CAF_VOID_STMT

#define CAF_PUSH_AID_FROM_PTR(unused) CAF_VOID_STMT

#define CAF_SET_AID(unused) caf_set_aid_dummy()

#define CAF_SET_LOGGER_SYS(unused) CAF_VOID_STMT

#define CAF_LOG_TRACE(unused)

#else // CAF_LOG_LEVEL

#define CAF_LOG_IMPL(loglvl, message)                                          \
  caf::logger::log_static(loglvl, CAF_GET_CLASS_NAME, __func__,                \
                          __FILE__, __LINE__,                                  \
                          (caf::logger::line_builder{} << message).get())

#define CAF_PUSH_AID(aarg)                                                     \
  auto CAF_UNIFYN(caf_tmp_ptr) = caf::logger::current_logger();                \
  caf::actor_id CAF_UNIFYN(caf_aid_tmp) = 0;                                   \
  if (CAF_UNIFYN(caf_tmp_ptr))                                                 \
    CAF_UNIFYN(caf_aid_tmp) = CAF_UNIFYN(caf_tmp_ptr)->thread_local_aid(aarg); \
  else                                                                         \
    printf("[ERROR] CAF_PUSH_AID called in file %s on line %d "                \
           "without thread-local logger pointer", __FILE__, __LINE__);         \
  auto CAF_UNIFYN(aid_aid_tmp_guard) = caf::detail::make_scope_guard([=] {     \
    auto CAF_UNIFYN(caf_tmp2_ptr) = caf::logger::current_logger();             \
    if (CAF_UNIFYN(caf_tmp2_ptr))                                              \
      CAF_UNIFYN(caf_tmp2_ptr)->thread_local_aid(CAF_UNIFYN(caf_aid_tmp));     \
  })

#define CAF_PUSH_AID_FROM_PTR(some_ptr)                                        \
  auto CAF_UNIFYN(caf_aid_ptr) = some_ptr;                                     \
  CAF_PUSH_AID(CAF_UNIFYN(caf_aid_ptr) ? CAF_UNIFYN(caf_aid_ptr)->id() : 0)

#define CAF_SET_AID(aid_arg)                                                   \
  (caf::logger::current_logger()                                               \
     ? caf::logger::current_logger()->thread_local_aid(aid_arg)                \
     : 0)

#define CAF_SET_LOGGER_SYS(ptr) caf::logger::set_current_actor_system(ptr)

#if CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(unused) CAF_VOID_STMT

#else // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(entry_message)                                           \
  caf::logger::trace_helper CAF_UNIFYN(caf_log_trace_) {                       \
    CAF_GET_CLASS_NAME, __func__, __FILE__, __LINE__,                          \
    (caf::logger::line_builder{} << entry_message).get()                       \
  }

#endif // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#endif // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output)
#define CAF_LOG_INFO(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output)
#define CAF_LOG_WARNING(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output)
#define CAF_LOG_ERROR(output)                                                  \
  do {                                                                         \
    CAF_PRINT_ERROR_IMPL(CAF_GET_CLASS_NAME, __func__, output);                \
    CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output);                                 \
  } while (false)

#ifdef CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output); } CAF_VOID_STMT

#define CAF_LOG_INFO_IF(cond, output)                                          \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output); } CAF_VOID_STMT

#define CAF_LOG_WARNING_IF(cond, output)                                       \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output); } CAF_VOID_STMT

#define CAF_LOG_ERROR_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output); } CAF_VOID_STMT

#else // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(unused1, unused2)
#define CAF_LOG_INFO_IF(unused1, unused2)
#define CAF_LOG_WARNING_IF(unused1, unused2)
#define CAF_LOG_ERROR_IF(unused1, unused2)

#endif // CAF_LOG_LEVEL

#endif // CAF_DETAIL_LOGGING_HPP
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Assembly.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "AssemblyItem.h"
#include <fstream>

using namespace std;
using namespace dev;
using namespace dev::eth;

AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const
{
	assertThrow(m_data < (u256(1) << 64), Exception, "Tag already has subassembly set.");

	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	AssemblyItem r = *this;
	r.m_type = PushTag;
	r.setPushTagSubIdAndTag(_subId, size_t(m_data));
	return r;
}

pair<size_t, size_t> AssemblyItem::splitForeignPushTag() const
{
	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	return make_pair(size_t(m_data / (u256(1) << 64)) - 1, size_t(m_data));
}

void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag)
{
	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	setData(_tag + ((u256(_subId) + 1) << 64));
}

unsigned AssemblyItem::bytesRequired(unsigned _addressLength) const
{
	switch (m_type)
	{
	case Operation:
	case Tag: // 1 byte for the JUMPDEST
		return 1;
	case PushString:
		return 33;
	case Push:
		return 1 + max<unsigned>(1, dev::bytesRequired(m_data));
	case PushSubSize:
	case PushProgramSize:
		return 4;		// worst case: a 16MB program
	case PushTag:
	case PushData:
	case PushSub:
		return 1 + _addressLength;
	case PushLibraryAddress:
		return 21;
	default:
		break;
	}
	BOOST_THROW_EXCEPTION(InvalidOpcode());
}

int AssemblyItem::deposit() const
{
	switch (m_type)
	{
	case Operation:
		return instructionInfo(instruction()).ret - instructionInfo(instruction()).args;
	case Push:
	case PushString:
	case PushTag:
	case PushData:
	case PushSub:
	case PushSubSize:
	case PushProgramSize:
	case PushLibraryAddress:
		return 1;
	case Tag:
		return 0;
	default:;
	}
	return 0;
}

string AssemblyItem::getJumpTypeAsString() const
{
	switch (m_jumpType)
	{
	case JumpType::IntoFunction:
		return "[in]";
	case JumpType::OutOfFunction:
		return "[out]";
	case JumpType::Ordinary:
	default:
		return "";
	}
}

ostream& dev::eth::operator<<(ostream& _out, AssemblyItem const& _item)
{
	switch (_item.type())
	{
	case Operation:
		_out << " " << instructionInfo(_item.instruction()).name;
		if (_item.instruction() == solidity::Instruction::JUMP || _item.instruction() == solidity::Instruction::JUMPI)
			_out << "\t" << _item.getJumpTypeAsString();
		break;
	case Push:
		_out << " PUSH " << hex << _item.data();
		break;
	case PushString:
		_out << " PushString"  << hex << (unsigned)_item.data();
		break;
	case PushTag:
	{
		size_t subId = _item.splitForeignPushTag().first;
		if (subId == size_t(-1))
			_out << " PushTag " << _item.splitForeignPushTag().second;
		else
			_out << " PushTag " << subId << ":" << _item.splitForeignPushTag().second;
		break;
	}
	case Tag:
		_out << " Tag " << _item.data();
		break;
	case PushData:
		_out << " PushData " << hex << (unsigned)_item.data();
		break;
	case PushSub:
		_out << " PushSub " << hex << size_t(_item.data());
		break;
	case PushSubSize:
		_out << " PushSubSize " << hex << size_t(_item.data());
		break;
	case PushProgramSize:
		_out << " PushProgramSize";
		break;
	case PushLibraryAddress:
		_out << " PushLibraryAddress " << hex << h256(_item.data()).abridgedMiddle();
		break;
	case UndefinedItem:
		_out << " ???";
		break;
	default:
		BOOST_THROW_EXCEPTION(InvalidOpcode());
	}
	return _out;
}
<commit_msg>Fix setting the tag.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Assembly.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "AssemblyItem.h"
#include <fstream>

using namespace std;
using namespace dev;
using namespace dev::eth;

AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const
{
	assertThrow(m_data < (u256(1) << 64), Exception, "Tag already has subassembly set.");

	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	AssemblyItem r = *this;
	r.m_type = PushTag;
	r.setPushTagSubIdAndTag(_subId, size_t(m_data));
	return r;
}

pair<size_t, size_t> AssemblyItem::splitForeignPushTag() const
{
	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	return make_pair(size_t(m_data / (u256(1) << 64)) - 1, size_t(m_data));
}

void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag)
{
	assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
	setData(_tag + (u256(_subId + 1) << 64));
}

unsigned AssemblyItem::bytesRequired(unsigned _addressLength) const
{
	switch (m_type)
	{
	case Operation:
	case Tag: // 1 byte for the JUMPDEST
		return 1;
	case PushString:
		return 33;
	case Push:
		return 1 + max<unsigned>(1, dev::bytesRequired(m_data));
	case PushSubSize:
	case PushProgramSize:
		return 4;		// worst case: a 16MB program
	case PushTag:
	case PushData:
	case PushSub:
		return 1 + _addressLength;
	case PushLibraryAddress:
		return 21;
	default:
		break;
	}
	BOOST_THROW_EXCEPTION(InvalidOpcode());
}

int AssemblyItem::deposit() const
{
	switch (m_type)
	{
	case Operation:
		return instructionInfo(instruction()).ret - instructionInfo(instruction()).args;
	case Push:
	case PushString:
	case PushTag:
	case PushData:
	case PushSub:
	case PushSubSize:
	case PushProgramSize:
	case PushLibraryAddress:
		return 1;
	case Tag:
		return 0;
	default:;
	}
	return 0;
}

string AssemblyItem::getJumpTypeAsString() const
{
	switch (m_jumpType)
	{
	case JumpType::IntoFunction:
		return "[in]";
	case JumpType::OutOfFunction:
		return "[out]";
	case JumpType::Ordinary:
	default:
		return "";
	}
}

ostream& dev::eth::operator<<(ostream& _out, AssemblyItem const& _item)
{
	switch (_item.type())
	{
	case Operation:
		_out << " " << instructionInfo(_item.instruction()).name;
		if (_item.instruction() == solidity::Instruction::JUMP || _item.instruction() == solidity::Instruction::JUMPI)
			_out << "\t" << _item.getJumpTypeAsString();
		break;
	case Push:
		_out << " PUSH " << hex << _item.data();
		break;
	case PushString:
		_out << " PushString"  << hex << (unsigned)_item.data();
		break;
	case PushTag:
	{
		size_t subId = _item.splitForeignPushTag().first;
		if (subId == size_t(-1))
			_out << " PushTag " << _item.splitForeignPushTag().second;
		else
			_out << " PushTag " << subId << ":" << _item.splitForeignPushTag().second;
		break;
	}
	case Tag:
		_out << " Tag " << _item.data();
		break;
	case PushData:
		_out << " PushData " << hex << (unsigned)_item.data();
		break;
	case PushSub:
		_out << " PushSub " << hex << size_t(_item.data());
		break;
	case PushSubSize:
		_out << " PushSubSize " << hex << size_t(_item.data());
		break;
	case PushProgramSize:
		_out << " PushProgramSize";
		break;
	case PushLibraryAddress:
		_out << " PushLibraryAddress " << hex << h256(_item.data()).abridgedMiddle();
		break;
	case UndefinedItem:
		_out << " ???";
		break;
	default:
		BOOST_THROW_EXCEPTION(InvalidOpcode());
	}
	return _out;
}
<|endoftext|>


<commit_before><commit_msg>include opencv2 (cpp headers) in order to avoid compiler error<commit_after><|endoftext|>